shell脚本详细介绍
一、概述
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言(就是你所说的shell脚本)。作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。
shell脚本:是使用shell编写的纯文本程序,其扩展名为sh。
查看自己系统的shell解析器
echo $SHELL
/bin/bash
二、shell语法
1、定义开头 #!/bin/bash
#!/bin/bash
2、注释
- 单行注释 :#
# 这是单行注释
- 多行注释
#其中EOF可以替换为其他字符
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
3、给shell脚本赋予执行权限
chmod 777 test.sh
chmod +x test.sh
文件权重占比
读:4
写:2
执行:1
4、变量
(1)变量命名规则
- 只能使用英文字母,数字和下划线,首字母不能以数字开头
- 中间不能有空格,可以使用下划线_
- 不能使用标点符号
- 不能使用 bash里的关键字(可以使用help查看保留关键字)
- 注意(变量和等号之间不能有空格)
(2)变量引用
变量名前加$
变量名前加${}
#!/bin/bash
name="test"
#变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界
echo $name
echo ${name}
(3)只读变量
使用readonly命令可以将变量定义为只读变量,当定义为只读变量后,值不能被修改;当修改只读变量时,会报错(shellName:只读变量)
#!/bin/bash
shellName="test01"
readonly shellName
shellName="test02"
(4)删除变量
使用unset命令可以删除变量,变量删除后不能再次使用,unset命令不能删除只读变量,报(unset: name02: 无法反设定: 只读 variable)
#!/bin/bash
name01="test01"
echo $name01
unset name01
echo ${name01}
#只读变量无法删除
name02="test02"
readonly name02
unset name02
echo $name02
(5)变量类型
- 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量
- 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来博爱正其正常运行。必要的时候shell脚本也可以定义环境变量
- shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
(6)shell字符串
1)单引号
-
单引号里的任何字符都会原样输出,单引号中的变量是无效的
-
单引号字符串中不能出现单独一个单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接
str='this is string'
2)双引号
-
双引号里可以有变量
-
双引号里可以出现转义字符
#!/bin/bash name="test" #使用双引号进行拼接 info_01="My name is "$name" !" echo $info_01 #使用单引号拼接(引用值添加单引号) info_02="My name is '$name' !" echo $info_02 #结果 My name is test ! My name is 'test' !
3)获取字符串长度
#!/bin/bash
name="test"
echo ${#name}
echo ${#name[0]}
4)查找子字符串
#!/bin/bash
test="this is string"
#查找s出现的位置
echo `expr index "$test" s`
#查找字符i或s出现的位置(哪个字符先出现就计算哪个)
echo `expr index "$test" is`
5)提取子字符串
#!/bin/bash
test="this is string"
#从字符串索引1开始,截取4个字符
echo ${test:1:4}
5、数组
(1)定义数组
#!/bin/bash
#第一种方式
array_01=(value0 value1 value2)
#第二种方式
array_02=(
value0
value1
value2
)
#第三种方式
array_03[0]=value0
array_03[1]=value1
array_03[2]=value2
(2)读取数组
#!/bin/bash
array=(1,2,3)
#根据索引获取 ${数组名[下标]}
value=${array[0]}
#使用@符号获取数组所有元素
echo ${array[@]}
(3)获取数组长度
#!/bin/bash
array=(1,2,3)
#获取元素数组个数
length=${#array[@]}
length=${#array[*]}
#获取数组元素的长度
lengthn=${#array[0]}
6、shell传递参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,0为执行的文件名(包含路径),1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与 ∗ 相 同 , 但 是 使 用 时 加 引 号 , 并 在 引 号 中 返 回 每 个 参 数 。 如 " *相同,但是使用时加引号,并在引号中返回每个参数。 如" ∗相同,但是使用时加引号,并在引号中返回每个参数。如"@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2"…"n” 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
$*和
$@的区别
- 相同点:都是引用所有参数
- 不同点:只有在双引号中体现出来。假设脚本中三个参数1,2,3,则*等于“123”(传递了一个参数),而@等价于"1" “2” “3”(传递三个参数)。
7、shell基本运算符
- expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
- 完整的表达式要被
(1)算术运算符
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余 |
= | 赋值 |
== | 相等。用于比较两个数字,相同则返回 true。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 |
(2)关系运算符
关系运算符支支持数字,不支持字符串,除非字符串的值是数字
常用关系运算符如下:
算符 | 说明 |
---|---|
-eq | 检测两个数是否相等,相等返回 true。 |
-ne | 检测两个数是否不相等,不相等返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 |
(3)布尔运算
运算符 | 说明 |
---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 |
(4)逻辑运算符
运算符 | 说明 |
---|---|
&& | 逻辑的 AND |
|| | 逻辑的 OR |
(5)字符串运算符
运算符 | 说明 |
---|---|
= | 检测两个字符串是否相等,相等返回 true。 |
!= | 检测两个字符串是否不相等,不相等返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 |
$ | 检测字符串是否不为空,不为空返回 true。 |
(6)文件测试运算符
操作符 | 说明 |
---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 |
-r file | 检测文件是否可读,如果是,则返回 true。 |
8、if语句
(1)if语句
if condition
then
command1
command2
...
commandN
fi
(2)if else 语句
if condition
then
command1
command2
...
commandN
else
command
fi
(3)if else-if else语句
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
9、循环
(1)for循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
#示例
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
(2)while循环
while condition
do
command
done
#示例
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
(3)until循环
until condition
do
command
done
#示例
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
(4)无限循环的情况
#第一种情况
while :
do
command
done
#第二种情况
while true
do
command
done
#第三种情况
for (( ; ; ))
10、shell函数
(1)shell函数格式
[ function ] funname [()]
{
action;
[return int;]
}
-
可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
-
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
demoFun(){ echo "这是我的第一个 shell 函数!" } echo "-----函数开始执行-----" demoFun echo "-----函数执行完毕-----"
(2)函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73