目录:
1.解释器
2.shell脚本
脚本执行
变量定义
特殊变量($开头的变量)
从命令行输入变量(read方法)
变量扩展(判断变量不存在使用默认值、字符串测量截取替换)
条件测试(文件测试、字符串、数值、条件符号&|)
控制语句(if else、case、for等)
函数
正文:
一.解释器
linux提供shell解释器有多种
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
其中sh和bash是默认的解释器,sh是bash的软链接,本质上是一个东西
[root@master2 bin]# ll /bin/ | grep bash
-rwxr-xr-x 1 root root 964536 Nov 25 2021 bash
lrwxrwxrwx 1 root root 4 Sep 14 2022 sh -> bash
echo $SHELL 可以查询当前shell解释器
二.shell脚本
脚本以 #!/bin/bash 开头指定解释器
1.脚本执行:
使用sh或者bash + 脚本的路径
sh helloworld.sh 不用赋予脚本+x权限
使用脚本的路径(需要可执行权限)
./helloworld.sh
2.变量定义:变量=值
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
(2)等号两侧不能有空格
(3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
(4)变量的值如果有空格,需要使用双引号或单引号括起来。
(5)export变量可以将变量提升为全局变量,export MYNAME=”my name is kevin”
双引号可以解析变量的值,单引号不可以,会将单引号中的内容作为一个字符串
上述变量的定义是临时的,针对一次shell,下次打开就没有了,如果想要永久的变量,需要修改/etc/profile或用户目录的.bash_profile,前者是整个系统的,后者是单个用户的
C=1+2
echo $C
结果:1+2
D=“I love banzhang”
echo $D
结果:I love banzhang
3.特殊变量
$n
$0表示脚本名称,$1-9表示第一到第九个参数,十以上的参数需要大括号包含,${10}
#!/bin/bash
echo "$0 $1 $2"
[root@master2]# sh testshell.sh x sss
testshell.sh x sss
$#
表示参数的个数
$*
表示命令行中所有的参数,所有的参数看成一个整体
$@
表示命令行中所有的参数,每个参数都区分对待
例子:
[root@master2]# cat testshell.sh
#!/bin/bash
echo "$0 $1 $2"
echo "$#"
echo "$*"
echo "$@"
[root@master2]# sh testshell.sh x sss ddddd
testshell.sh x sss
3
x sss ddddd
x sss ddddd
$?
最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行
如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确
[root@master2]# echo $?
0
$$
表示当前进程号
[root@master2 zykfile]# cat testshell.sh
#!/bin/bash
echo "$$"
[root@master2 zykfile]# sh testshell.sh
21866
特殊符号:
""双引号可以解析变量的值
''单引号不可以解析变量的值,会将单引号中的内容作为一个字符串
``反引号中的内容是一条命令,可以执行
$()和``的效果一样,可以执行的命令
\转义字符,需要配合-e使用,echo -e "xx\nx"
()括起来子shell,其中的变量赋值不会影响到当前shell的变量
{}当前shell,会影响当前shell的变量
4.从命令行输入变量:
使用read关键字,同时定义了变量。-p可以输出描述
[root@master2]# cat testshell.sh
#!/bin/bash
echo "$0 $1 $2"
read -p "输入:" num
echo "$num"
[root@master2]# sh testshell.sh x sss ddddd
testshell.sh x sss
输入:123456
123456
read多个输入参数
[root@master2]# cat testshell.sh
#!/bin/bash
echo "$0 $1 $2"
read -p "输入:" num num1
echo "$num $num1"
[root@master2]# sh testshell.sh x sss ddddd
testshell.sh x sss
输入:123 456
123 456
5.变量扩展
1.判断变量是否存在,不存在的话使用默认值,格式为:${num:-100}
[root@master2]# cat testshell.sh
#!/bin/bash
echo "${num:-100}"
num=500
echo $num
[root@master2]# sh testshell.sh
100
500
2.字符串操作
测量字符串长度:#字符串
从下标处截取字符:字符串:下标
从下标处截取n个字符:字符串:下标:n
[root@master2]# cat testshell.sh
#!/bin/bash
string="123456789qwertyuiop"
echo "${#string}"
echo ${string:3}
echo ${string:3:6}
[root@master2]# sh testshell.sh
19
456789qwertyuiop
456789
3.字符串替换输出
输出的时候替换第一个出现的字符:字符串/aa/bb
[root@master2]# cat testshell.sh
#!/bin/bash
string="123456789qwertyuiop"
echo ${string/qwer/asdf}
echo $string
[root@master2]# sh testshell.sh
123456789asdftyuiop
123456789qwertyuiop
输出的时候替换所有字符:字符串//aa/bb
[root@master2]# cat testshell.sh
#!/bin/bash
string="qwertyuiopqwertyuiop"
echo ${string//qwer/asdf}
echo $string
[root@master2]# sh testshell.sh
asdftyuiopasdftyuiop
qwertyuiopqwertyuiop
6.条件测试,用于测试字符串、文件状态等
格式为:test condition 或[ condition ],方括号的两边需要加一个空格。任何逻辑操作符号和字符之间都需要加一个空格!!!
(1)文件测试:
-e 是否存在
-d 是目录
-f 是文件
-r 可读
-w 可写
-x 可执行
-L 符号链接
-c 字符设备
-b 块设备
-s 文件非空,$?返回1表示文件空,返回0表示文件不空
举例:[ -e /root/zzzz ]
[root@master2]# cat testshell.sh
#!/bin/bash
read file
[ -e $file ]
echo $?
[root@master2]# sh testshell.sh
/root/zzz
0
[root@master2]# sh testshell.sh
/root/zzzzz
1
(2)字符串测试
= 字符串相等
!= 字符串不相等
-z 空串
-n 非空串
[root@master2]# cat testshell.sh
#!/bin/bash
tstring="asdfghjkl"
astring="asdfghjkl"
[ -z $tstring ]
echo $?
[ -n $tstring ]
echo $?
[ $tstring = $astring ]
echo $?
[ $tstring != $astring ]
echo $?
[root@master2]# sh testshell.sh
1
0
0
1
(3)数值测试
-eq 相等 equal
-ne 不相等 not e
-gt 大于 greater than
-ge 大于等于 greater equal
-lt 小于 less than
-le 小于等于 less equal
[root@master2]# cat testshell.sh
#!/bin/bash
a=1
b=1
c=2
d="-1"
[ $a -eq $b ]
echo $?
[ $a -ne $b ]
echo $?
[ $a -ge $b ]
echo $?
[ $a -gt $c ]
echo $?
[ $a -gt $d ]
echo $?
[root@master2]# sh testshell.sh
0
1
0
1
0
(4)符合语句测试
&& 前面语句如果执行成功,才执行后面语句
[root@master2]# cat testshell.sh
#!/bin/bash
[ "aaa" = "aaa" ] && [ "a" = "a" ] && echo "success"
[root@master2]# sh testshell.sh
success
|| 前面语句执行失败,才执行后面语句
[root@master2]# cat testshell.sh
#!/bin/bash
[ "aaa" = "aaa" ] && [ "aa" = "aaia" ] || echo "success"
[root@master2]# sh testshell.sh
success
-a 前后条件同时成立
-o 前后条件任一成立
! 不成立
[root@master2]# cat testshell.sh
#!/bin/bash
[ "aaa" = "aaa" -a "aaa" = "aaa" ] && echo "success"
[root@master2]# sh testshell.sh
success
[root@master2 zykfile]# cat testshell.sh
#!/bin/bash
[ "aaa" = "aaa" -o "aa" = "aaa" ] && echo "success"
[root@master2 zykfile]# sh testshell.sh
success
[root@master2 zykfile]# cat testshell.sh
#!/bin/bash
[ ! "aaaa" = "aaa" ] && echo "success"
[root@master2 zykfile]# sh testshell.sh
success
7.控制语句
(1)if语句
格式一:
if [条件1]; then
else
fi
格式二:
if [条件1]; then
elif [条件2];then
else
fi
举例
如果目录不存在,则创建目录后创建文件,如果目录存在,直接创建文件
#!/bin/bash
dir="/root/zykfile/shellt"
if [ -e $dir ] ; then
echo "目录存在"
cd $dir
touch zykzyk.c
else
echo "目录不存在"
mkdir $dir
cd $dir
touch zykzyk.c
fi
#!/bin/bash
dir="/root/zykfile/shellt"
if [ -e $dir ] ; then
echo "目录存在"
cd $dir
touch zykzyk.c
elif [ "a" = "a" ] ; then
echo "目录不存在"
mkdir $dir
cd $dir
touch zykzyk.c
fi
(2)case语句
格式:其中case * 表示default,;;表示break
case $变量 in
变量名称1)
语句
;;
变量名称2)
语句
;;
*)
语句
;;
esac
举例,根据输入进行输出,可以模糊匹配
[root@master2]# cat testshell.sh
#!/bin/bash
read str
case $str in
a)
echo "aaa"
;;
"b" | b* | B*)
echo "bbb"
;;
*)
echo "other"
;;
esac
[root@master2]# sh testshell.sh
a
aaa
[root@master2]# sh testshell.sh
b
bbb
[root@master2]# sh testshell.sh
baaaaa
bbb
[root@master2]# sh testshell.sh
Bjjj
bbb
[root@master2]# sh testshell.sh
aaaa
other
(3)for语句
格式一:和java类似
for (( 初始值;限制值;步阶 ))
do
语句
done
格式二:第一次循环,$var内容是con1,以此类推
for var in con1 con2 con3
do
语句
done
举例,循环n次
declare是内建命令,declare -i s,代表将s变量当作int类型计算
获取当前目录文件,循环输出文件类型
[root@master2]# cat testshell.sh
#!/bin/bash
declare -i sum
declare -i i
for (( i=0; i<=10; i++ ))
do
sum=$sum+$i;
echo $sum
done
[root@master2]# sh testshell.sh
0
1
3
6
10
15
21
28
36
45
55
[root@master2]# cat testshell.sh
#!/bin/bash
declare -i sum
declare -i i
for i in 1 2 3 4
do
sum=$sum+$i;
echo $sum
done
[root@master2]# sh testshell.sh
1
3
6
10
[root@master2]# cat testshell.sh
#!/bin/bash
for name in `ls`
do
if [ -d $name ]; then
echo "$name是文件夹"
elif [ -f $name ]; then
echo "$name是文件"
fi
done
[root@master2]# sh testshell.sh
xxx是文件
server.crt是文件
server.csr是文件
server.key是文件
shellt是文件夹
(4)while语句,条件满足时不断循环
格式
while [ condition ]
do
代码
done
举例,字符串拼接,直到while条件满足
[root@master2]# cat testshell.sh
#!/bin/bash
s=""
while [ "$s" != "sss" ]
do
s="${s}s"
done
echo $s
[root@master2]# sh testshell.sh
sss
可以使用while true,表示无限循环
(5)until语句,条件满足时跳出循环
格式
until [ condition ]
do
代码
done
举例,字符串拼接,满足条件时跳出循环
[root@master2]# cat testshell.sh
#!/bin/bash
s=""
until [ "$s" = "sss" ]
do
s="${s}s"
done
echo $s
[root@master2]# sh testshell.sh
sss
(6)break,continue
和java用法一样,用于跳出循环
[root@master2]# cat testshell.sh
#!/bin/bash
s=""
until [ "$s" = "sss" ]
do
s="${s}s"
if [ "$s" = "ss" ]; then
break
fi
done
echo $s
[root@master2]# sh testshell.sh
ss
8.函数
函数在使用前必须定义,放在脚本的开始部分
格式一
函数名() {
代码
}
格式二
function 函数名() {
代码
}
使用函数时:函数名 param1 param2
和脚本中使用特殊变量$1 $2一样,函数中也可以这样使用入参
函数可以使用return 提前结束并带有返回值
[root@master2]# cat testshell.sh
#!/bin/bash
function maxnum (){
if [ $1 -gt $2 ]; then
return $1
else
return $2
fi
}
read data1 data2
maxnum $data1 $data2
echo "max is $?"
[root@master2]# sh testshell.sh
12 13
max is 13
函数的返回:
1.return返回
return返回只支持数字0-255,超过255则从0开始计算。通常返回0作为成功,1表示失败,状态码可以自定义
如果函数中只写一个return,表示return 0,两个是等价的。如果函数中没有return语句,则使用默认的退出状态,即最后一条命令的退出状态码
获取函数结果,可以用$?
2.echo返回
没有return时,函数以最后一条命令的运行结果作为返回值,因此可以在最后一行使用echo ""作为返回值,如果有多条echo,也只会以最后一个echo为返回值
获取函数结果,可以赋值结果给变量,string=$(get_string)
3.exit
exit是一个系统调用级别的函数,在进程层面工作,表示进程的退出
exit 0表示脚本执行成功
exit 其他数字表示脚本执行失败,数字可以自定义
获取脚本执行成功失败可以用$?
return是函数级别的退出,本身是关键字,表示退出函数
函数导入
一个脚本可以引用另一个脚本
在脚本开始编写:source xxx.sh,函数就可以直接用函数名调用
引用后会将另一个脚本中的命令也都执行掉,所以另一个脚本中最好只定义函数,不编写命令