shell编程

shell是什么东西?

  Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(command interpreter,命令解析器)。它类似于DOS下的COMMAND.COM和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。

在这里插入图片描述

  Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强的特点

  简单来说,Shell脚本给用户操作内核提供了接口,同时也可以对命令赋予了逻辑,什么时候执行什么命令都可以有编程人员进行设计

java程序员为什么要学习Shell?

1、看懂运维人员编写的Shell程序
  Shell脚本相当于对底层命令的一个封装,在服务上线/维护的时候,运维人员一般会编写Shell脚本批量执行命令来管理服务。java程序员需要和运维人员沟通,能看懂Shell程序是最基本的前提

2、偶尔会编写一些简单的Shell程序来方便开发
  对于一些复杂的过程,程序员可以使用简单的shell脚本使其变得简单起来。在开发过程中,通常需要使用到mysql、nacos、redis、rabbitMQ等等第三方工具,如果逐个启动/关闭,那就太麻烦了,此时就可以写个Shell脚本一键启动/关闭服务。另外地还有其它许多好用的Shell可以简便我们的开发

Shell的解析器

查看Shell的解析器命令:cat /etc/shells
在这里插入图片描述
可以看到,Shell语言的解析器有sh、bash等

查看目录详情:cll /bin/ | grep bash

在这里插入图片描述
实际上,sh是bash的软链接,就是使用sh解析器的时候实际使用的是bash解析器

第一个Shell脚本

1、编写脚本

创建my_sh目录:mkdir -p /home/my_sh/
创建并编写一个hello.sh脚本:vim /home/my_sh/hello.sh

输入以下内容:

#!/bin/bash

echo "hello world!"

默认各位都会linux基础了嗷,如果不会操作建议先学习linux基础

在这里插入图片描述

# 是注释的意思
#! 是指定解析器的意思,这里需要区分

echo 是相当于print,打印的意思

整个程序就是打印 helloworld!这一句话的意思

2、运行脚本

用绝对路径
命令:sh /home/my_sh/hello.sh
命令:bash /home/my_sh/hello.sh
命令:/home/my_sh/hello.sh

在这里插入图片描述
直接使用/home/my_sh/hello.sh发现权限不够,那是因为该文件没有可执行的权限,可以通过chmod分配权限解决

分配权限 chmod 777 /home/my_sh/hello.sh

再次执行:
在这里插入图片描述

用相对路径
需要先进入到/home/my_sh目录下:cd /home/my_sh/
命令:sh hello.sh
命令:bash hello.sh
命令:./hello.sh

在这里插入图片描述
./代表当前路径,使用相对路径时,需要使用./hello.sh,而不可以直接使用hello.sh

Shell中的变量

1、系统环境变量
  在系统环境配置文件/etc/profile文件或/etc/profile.d/下的所有xx.sh文件中配置的环境变量,可以以$xxx的方式直接获取
例如:
echo $HOME
echo $USER
echo $SHELL
echo $JAVA_HOME
在这里插入图片描述
JAVA_HOME是我自己配置的环境变量

2、用户自定义变量

  自定义变量可直接以=赋值,以$xxx的方式获取值
例如:A=1
打印:echo $A

在这里插入图片描述

注意: 等号两边不允许出现空格!A = 1、A= 1、A =1这些形式都是不可以的,是错误的
在这里插入图片描述

如果值存在特殊字符!&$、空格等特殊字符时,需要用单引号括起来
A=!&$ ggg
echo $A
A=‘!&$ ggg’

A='!&$ ggg'

echo $A

注意: 上面的单引号需要改为英文的,因为编码原因,请复制代码块里的代码
在这里插入图片描述

3、特殊变量

(1)$n: n为数字,$0代表脚本名称,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10},实则所有参数获取的方式都是${n},只是0-9的被简化为了$n而已

创建param脚本:vim /home/my_sh/param.sh
输入以下信息:

#!/bin/bash
echo "$0 $1 $2 ${3} ${4}"

在这里插入图片描述

执行脚本:sh /home/my_sh/param.sh

执行脚本:sh /home/my_sh/param.sh 参数1 参数2 参数3 参数4 参数5

在这里插入图片描述
可以发现,前面脚本名和前面4个参数都成功接收了

(2)$#: 获取所有输入参数的个数,参用于循环
编辑param脚本:vim /home/my_sh/param.sh
输入以下信息:

#!/bin/bash
echo "$0 $1 $2 ${3} ${4}"
echo $#

执行脚本:sh /home/my_sh/param.sh

执行脚本:sh /home/my_sh/param.sh 参数1 参数2 参数3 参数4 参数5

在这里插入图片描述
(3)$*、$@
$*: 代表命令行中所有参数,$*把所有的参数看出一个整体
$@: 代表命令行中所有参数,$@把每个参数区分看待

编辑param脚本:vim /home/my_sh/param.sh
输入以下信息:

#!/bin/bash
echo "$0 $1 $2 ${3} ${4}"
echo $#
echo $*
echo $@

执行脚本:sh /home/my_sh/param.sh

执行脚本:sh /home/my_sh/param.sh 参数1 参数2 参数3 参数4 参数5

在这里插入图片描述
这里是看不出区别的,但是在循环里就容易看出来的
编辑param脚本:vim /home/my_sh/param.sh
输入以下信息:

#!/bin/bash
echo "$0 $1 $2 ${3} ${4}"
echo $#
for parm in "$*"
do
	echo $parm
done

for parm in "$@"
do
	echo $parm
done

执行脚本:sh /home/my_sh/param.sh 参数1 参数2 参数3 参数4 参数5
在这里插入图片描述

(4)$? : 最后一次执行的命令的返回状态。如果这个变量值为0,代表上一个命令正确执行。否则执行失败(具体是哪个数,由命令自己来决定)

测试:
sh /home/my_sh/hello.sh
echo $?
sh /home/my_sh/
echo $?

在这里插入图片描述

Shell的运算符

在Shell程序中,所有的数据类型默认是字符串,如果想要对数据进行运算,那么必须使用一定运算范式

例如:
命令:echo 1+1
在这里插入图片描述
并没有进行运算

(1) expr +、-、*、/、%   加、减、乘、除、取余

注意:expr运算符间要有空格

例如:
expr 1 + 1
expr 1 \* 2
expr 5 % 2

在这里插入图片描述

括号运算:(2+3)*6
命令:expr `expr 2 + 3` \* 6
在这里插入图片描述

(2) $((运算式))或$[运算式]

两种运算方式都是一样的,只是形式不同,都可以直接进行括号运算

例如:
echo $((1+1))
echo $((1*2))
echo $((5%2))
echo $(((2+3)*6))

echo $[1+1]
echo $[1*2]
echo $[5%2]
echo $[(2+3)*6]

在这里插入图片描述

Shell的条件判断

1、基本语法
[ condition ]

注意:condition前后一定要有空格,条件非空即为true,[ abc ] 返回true,[] 返回false

2、常用判断条件
(1)两个整数之间的比较

条件解释
-lt小于 (less than)
-le小于等于 (less equal)
-eq等于 (equal)
-gt大于 (greater than)
-ge大于等于 (greater equal)
-ne不等于 (not equal)

(2)按照文件权限进行判断

条件解释
-r有读权限的 (read)
-w有写权限的 (write)
-x有执行权限的 (execute)

(3)按照文件类型进行判断

条件解释
-f文件存在并且是一个常规文件 (read)
-e文件存在 (write)
-d文件存在并且是一个目录 (execute)

Shell的if语句

1、基本语法

if [ 条件判断式 ] 
	then
		程序
elif [ 条件判断式 ]
	then
		程序
else 
	程序
fi

注意:if和else if后都要跟空格,[ 条件 ] 条件前后也要加空格

2、测试
  输入分数大于等于90打印优秀,小于90大于等于60打印及格,其它的输出太菜了

创建if.sh脚本:vim /home/my_sh/if.sh

输入以下内容

#!/bin/bash

if [ $1 -ge 90 ] 
	then
		echo 优秀
elif [ $1 -ge 60 ]
	then
		echo 及格
else 
	echo 太菜了
fi

在这里插入图片描述

运行程序:
sh /home/my_sh/if.sh 90
sh /home/my_sh/if.sh 70
sh /home/my_sh/if.sh 60
sh /home/my_sh/if.sh 50

在这里插入图片描述

Shell的case语句

1、基本语法

case $变量名 in
	"值1")
		如果变量的值等于值1,则执行程序1
		;;
		
	"值2")
		如果变量的值等于值2,则执行程序2
		;;
		
	"值3")
		如果变量的值等于值1,则执行程序3
		;;
		
	*)
		如果变量的值都不等于以上的值,则执行该程序
		;;
esac

解释:
case开头,esac结尾。
对于每个分支,以两个分号结尾

2、测试
输入一个参数
参数如果为1,打印 你好,张三
参数如果为2,打印 你好,李四
参数如果为3,打印 你好,王五
参数如果为其它,打印 谁啊你

创建case.sh脚本:vim /home/my_sh/case.sh

输入以下内容:

#!/bin/bash
case $1 in
	1)
		echo 你好,张三
		;;
		
	2)
		echo 你好,李四
		;;
		
	3)
		echo 你好,王五
		;;
		
	*)
		echo 谁啊你
		;;
esac

在这里插入图片描述

执行程序:

sh /home/my_sh/case.sh 1
sh /home/my_sh/case.sh 2
sh /home/my_sh/case.sh 3
sh /home/my_sh/case.sh 4

在这里插入图片描述

Shell的for语句

1、两种for语法

#for循环方法1
for((初始值;循环控制条件;变量变化))
do
	程序
done


#for循环方法2
for 变量名 in 集合名
do
	程序
done
	

2、测试
两种for循环求1+2+3+…+99+100的值

创建for.sh脚本:vim /home/my_sh/for.sh

输入以下内容:

#!/bin/bash
#for循环方法1
sum1=0
sum2=0
for((i=1;i<=100;i++))
do
	sum1=$[$sum1+$i]
done


#for循环方法2
for i in {1..100}
do
	sum2=$[$sum2+$i]
done
echo sum1=$sum1
echo sum2=$sum2

执行程序:sh /home/my_sh/for.sh
在这里插入图片描述

Shell的while语句

1、基本语法

while [ 条件判断式 ]
do
	程序
done

2、测试
while循环求1+2+3+…+99+100的值

创建while.sh脚本:vim /home/my_sh/while.sh

输入以下内容:

#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
	sum=$[$sum+$i]
	i=$[$i+1]
done
echo sum=$sum

在这里插入图片描述

Shell控制台输入

1、基本语法

read (选项) (参数)

选项:

选项解释
-p指定读取值时的提示符
-t指定读取值时等待的时间

参数:
变量:指定的读取值的变量名

2、示例

创建read.sh脚本:vim /home/my_sh/read.sh

输入以下内容:

#!/bin/bash
read -t 10 -p "请在10秒钟内输入您的姓名 " name
echo 您的名字为 $name

在这里插入图片描述
可以看到10秒钟不输入的话会跳过输入,继续执行后面的代码

Shell的系统函数

1、basename基本用法

basename [string/pathname] [suffix]

说明:
(1) basename命令会删除掉所有的前缀包括最后一个 ’/‘ 字符,然后以字符串的形式显示出来
(2) suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉

2、basename示例
截取 /home/mysql/data.txt 路径的文件名称

命令:
basename /home/mysql/data.txt
basename /home/mysql/data.txt .txt

在这里插入图片描述
3、dirname基本用法
dirname 文件绝对路径

说明:
(1) dirname从给定的包含绝对路径的文件名中去除文件名,然后返回剩下的路径。

3、dirname示例
截取 /home/mysql/data.txt 文件的路径名称

命令:dirname /home/mysql/data.txt

在这里插入图片描述

Shell自定义函数

1、基本语法

#方式1
function funname
{
	Action
	return int
}

#方式2
funname()
{
	Action
	return int
}

2、说明
(1) 必须在调用函数地方之前,先声明函数,shell脚本是逐行运行的。不会像其它语言一样先编译。

(2) 函数返回值,只能通过 $? 系统变量获得,可以显示加 return 返回,如果不加,将以最后一条命令运行结果(执行正确为0,执行错误为其它),作为返回值。return 后跟数值 n(0-255)

3、测试

fun函数接收任意个参数,求参数的和

创建my_fun.sh脚本:vim /home/my_sh/my_fun.sh

输入以下内容:

#!/bin/bash
function getsum
{
	sum=0
	for i in $@
	do
		((sum+=i))
	done
	return $sum
}
getsum 10 55 20
echo $?

运行脚本:sh /home/my_sh/my_fun.sh

在这里插入图片描述

e m s p ; emsp; emsp;emsp;此处我们借助 return 关键字将所有数字的和返回,并使用$?得到这个值,这种处理方案在其它编程语言中没有任何问题,但是在 Shell 中是非常错误的,Shell 函数的返回值和其它编程语言大有不同,返回值0代表程序执行没有异常,其它代表着程序执行失败

e m s p ; emsp; emsp;emsp;所以不应该这样使用返回值,可以直接在函数中打印数据

编辑my_fun.sh脚本:vim /home/my_sh/my_fun.sh

输入以下内容:

#!/bin/bash
function getsum
{
	sum=0
	for i in $@
	do
		((sum+=i))
	done
	echo sum=$sum
}
getsum 10 55 20
echo 返回值=$?

运行脚本:sh /home/my_sh/my_fun.sh

在这里插入图片描述

Shell工具——Cut

  cut就是就是剪的意思,该工具就是剪切数据用的。cut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出

1、基本用法
cut [选项参数] filename

参数功能
-f符号,提取第几列
-d分隔符,按照指定分割符分割列

2、准备数据

创建data.txt数据:vim /home/my_sh/data.txt
输入以下内容:

ni hao a
hello world !
shen zhen guan

在这里插入图片描述
3、测试
命令:
cut -d " " -f 1 /home/my_sh/data.txt
cut -d " " -f 1,2 /home/my_sh/data.txt
cut -d " " -f 1,3 /home/my_sh/data.txt
在这里插入图片描述

Shell工具——Sed

  sed是一种编辑器,它是一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为 “模式空间” ,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,不断重复,知道文件末尾。文件内容并没有改变,除非使用重定向存储输出

1、基本用法
sed [选项参数] ‘command’ filename

选项参数:

参数功能
-e直接在指令列模式上进行sed动作编辑

命令功能描述:

命令功能描述
a新增,a的后面可以接字符串,前面接数字,代表在第几行后面加上该字符串
d删除
s查找并替换

2、测试
(1) 在第二行后面添加“ni wo ta”

sed "2a ni wo ta" /home/my_sh/data.txt

(2) 删除包含 hello 的行

sed "/hello/d" /home/my_sh/data.txt

(3) 将文中所有的 hello 替换为 hi

sed "s/hello/hi/g" /home/my_sh/data.txt

g是global,全局的意思
(4) 删除第一行,将文中所有的 hello 替换为 hi

sed -e "1d" -e "s/hello/hi/g" /home/my_sh/data.txt

用-e执行多个流命令即可
在这里插入图片描述

Shell工具——Awk

  一个强大的文本分析工具,把文件逐行读入,以空格为默认分隔符,将每行切片,切开的部分再进行分析处理。
1、基本语法
awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename

pattern: 表示AWK在数据中查找的内容,就是匹配模式
action: 在找到匹配内容时所执行的一系列命令

参数功能
-F指定输入文件的分隔符
-v赋值一个用户定义变量

2、测试
(0) 搜索文件以 ni 开头的所有行,并输出该行的第1列和第3列,用 ‘,’ 分割

awk '/^ni/{print $1","$3}' /home/my_sh/data.txt

^ni是正则表达式,以ni开头的意思

(2) 显示第1和第3行,在第一行前面添加“hei hei”,在最后一行添加“ha ha”

awk 'BEGIN{print "hei hei"} {print $1,$3} END{print "ha ha"}' /home/my_sh/data.txt

BEGIN、END可以指定第一行、最后一行
在这里插入图片描述
3、awk的内置变量

变量说明
FILENAME文件名
NR已读的记录数
NF切割后列的个数

(1) 统计data.txt文件的文件名、行号和列数

awk '{print "文件名:" FILENAME ", 行号:" NR ", 列数:" NF}' /home/my_sh/data.txt

在这里插入图片描述

Shell工具——Sort

  sort命令非常常用,作用是将文件内容排序输出

1、基本语法

sort (选项) 文件名

选项说明
-n按照数值得大小从小到大排序
-r以相反的顺序来排序
-t设置排序时所用得分隔字符
-k指定需要排序得列

2、测试
(1) data.txt文件按每行第1列从小到大排序

sort /home/my_sh/data.txt

分隔符默认为空格

(2) data.txt文件按每行第3列从大到小排序

sort -rk 3 /home/my_sh/data.txt

分开写也是可以的

sort -r -k 3 /home/my_sh/data.txt

在这里插入图片描述

Shell面试题

(1) 使用Linux命令查询file.txt中空行所在的行号

awk '/^$/{print NR}' file.txt

在这里插入图片描述
在这里插入图片描述

(2) 有文件chengji.txt内容如下:

张三 20
李四 40
王五 40

统计第二列的和

cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'

在这里插入图片描述

(3) shell脚本判断一个文件是否存在

#!/bin/bash
if [ -f $1 ]
then
	echo "文件存在"
else
	echo "文件不存在"
fi

在这里插入图片描述
(4) 如果给定字符串 variable=“User:123:321:/home/dir”,如何只用 echo 命令获取 home_dir ?

#方式1
echo ${variable#*:*:*:}

#方式2
echo ${variable##*:}

在这里插入图片描述

(5) 写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令

#方式1
for i in {0..100..3}; do echo $i; done

#方式2
for (( i=0; i<=100; i=i+3 )); do echo $i;done

在这里插入图片描述

觉得不错就点个赞吧!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旧林墨烟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值