【格式】
以 #!/bin/[解释器类型] 作为脚本内容的第一行。
比如使用的解释器为 bash,那么第一行就写 #!/bin/bash。同理,若解释器为 sh 就写 #!/bin/sh
如果脚本首行没有这句话,shell 的默认脚本解释器又不是你想用的解释器,那么执行脚本可能会出错。
脚本文件的后缀为 .sh。扩展名只是为了让用户更容易区分文件,没有扩展名的脚本也能运行。
执行脚本前要先使用命令 chmod +x filename.sh 为脚本添加可执行权限。
【注释】
使用 # 作为注释符号。没有多行注释,只能每一行加一个 # 号。
【变量】
分为 局部变量、环境变量、shell变量 3种。
一般变量:
variable_name=variable_value 声明变量或对变量赋值。 等号两侧不能有空格。
variable_name=`command` 将命令 command 的执行结果赋值给变量 variable_name。 符号 ` 是反引号,位于 Esc 键下方。
read variable_name 从 stdin 获取输入并赋值给 variable_name 变量
readonly variable_name 这条命令可以将变量 variable_name 设置为只读。
unset variable_name 删除变量 variable_name
特殊变量:
\$\$ 当前 shell 进程的PID。使用: echo \$\$(斜杠\ 在这里只用于转义,实际使用时应该只有 2 个美元符号而不输入斜杠)
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。$1 表示第一个参数,$2 表示第二个参数。
$# 传递给脚本或函数的参数个数
$* 传递给脚本或函数的所有参数。"$*"会将所有传入参数视为一个字符串。
$@ 传递给脚本或函数的所有参数。"$@"会将传入参数视为不同的字符串。$* 和 $@ 含义相同。注意有没有使用引号""的区别。
$? 上个命令的退出状态,或函数的返回值。一般命令执行成功返回0,否则返回非零值。
使用变量时要在变量名前加$,并且变量可以在引号中使用。例如 echo "Welcome, $name."
为了避免混淆,可以使用花括号将变量括起来。例如 echo "There are 2 ${animal}s."。
变量替换:
${var:-word} 如果变量 var 为空或已被删除,那么返回 word,但不改变 var 的值。
${var:=word} 如果变量 var 为空或已被删除,那么返回 word,并将 var 的值设置为 word。
${var:?message} 如果变量 var 为空或已被删除,那么将 message 输出到标准错误输出,并终止脚本运行。
${var:+word} 如果变量 var 已被定义,那么返回 word,但不改变 var 的值。
数组:
bash只支持一维数组,下标从 0 开始,没有长度限制。使用括号表示数组,使用空格隔开数组元素。
命令 array_name=(value0 value1 value2 ... valueN) 或者
命令 array_name=(
value0
value1
...
valueN
)
均可用于声明并定义一个数组。
array_name[N] 用于操作某个数组元素。
${array_name[N]} 表示某个数组元素的值。
array_name[*] 或 array_name[@] 表示数组中的所有元素。
${array_name[*]} 或 ${array_name[@]} 表示数组中所有元素的值。
${#array_name[*]} 或 ${#array_name[@]} 表示数组元素的个数。
${#array_name[N]} 表示某个数组元素的长度。
【数据输出】
echo -e "hello world!\n" 将输出 hello world![回车]。参数 -e 的功能是开启转义。
echo "hello world!\n" 将输出 hello world!\n。默认不进行转义。
printf "%d %s \n" 1949 "China" 将输出 1949 China[回车]。
用法与 C中 printf() 类似,区别在于调用时不必使用括号,传入的实参用空格隔开且格式化字符串可以重用。比如:
printf "%s %s %s\n" a b c d e f g h i j 的打印结果为:
a b c
d e f
g h i
j
command > /dev/null 2>&1 屏蔽标准输出stdout 和标准错误输出stderr
【数据输入】
read variable_name 从 stdin 读取数据存入变量 variable_name 中
【运算】
数值运算:
使用命令 expr 作为中介实现数值运算。
比如 val=`expr 2 + 2`;echo -e "Total value is: %{val}\n"
需要注意的是运算符和运算数之间必须用空格隔开,写成 2+2 是错误的。
乘法运算符 * 在使用时需要进行转义。比如 val=`expr $input \* 5`
逻辑运算:
常见于 if条件语句的判断语句中
== 数值相等,if[ $a == $b ];then
!= 数值不等,或字符串不同
-eq 数值相等
-ne 数值不等,if[ $c -ne $d ];then
-gt 数值大于
-ge 数值大于等于
-lt 数值小于
-le 数值小于等于
! 非,if[ !$val ];then
-o 或,if[ $a -gt 20 -o $b -gt 20 ];then
-a 且,if[ $c -eq 0 -a $d -le 100 ];then
= 字符串相同,if[ $str1 = $str2 ]
-z 字符串长度为零,if[ -z $str ]
-n 字符串长度不为零,if[ -n $str ]
str 字符串str是否为空,if[ str ]
-e 检测文件或目录是否存在,if[ -e $filedir ]
-s 检测文件是否为空
-b 检测文件是否为块设备文件
-c 检测文件是否为字符设备文件
-d 检测文件是否为目录
-f 检测文件是否是普通文件
-r 检测文件是否可读
-w 检测文件是否可写
-x 检测文件是否可执行
-g 检测文件是否设置了 SGID 位
-u 检测文件是否设置了 SUID 位
-k 检测文件是否设置了粘着位(Sticky Bit)
-p 检测文件是否是具名管道
字符串操作:
string="abcdefg"
echo ${#string} # 获取字符串 string 长度,输出 7
echo ${string:1:4} # 提取子字符串,输出 bcde
echo `expr index "$string" ef` # 查找子字符串 ef 在 $string 中的位置
【流程控制】
退出脚本:
exit NUM 退出脚本,并将状态号置为 NUM
条件语句:
需要注意的是在判断语句后,在 then 之前需要写分号; 才能将 if 和 then 写成 1 行,否则应该分成 2 行写。
判断语句使用 中括号[] 括起来,且表达式 expression 和 中括号[] 之间必须用空格隔开,否则会出现语法错误。
if [ expression ] ; then
....
elif [ expression ] ; then
....
else
....
fi
选择语句:
case VALUE in
value 1)
command1
;; # 两个分号,类似于 C 中的 break
value 2)
command2
;;
*) # 类似于 C 中的 default
commandDefault
;;
esac
for循环语句:
循环语句的执行范围 LIST 是一组值组成的序列,如数字序列、字符串、文件集合等,并且序列中的每个值用空格分隔。
for VAR in LIST;do
command1
command2
...
commandN
done
while循环语句:
while [ expression ];do
command1
command2
...
commandN
done
until循环语句:
until循环与while循环再处理方式上刚好相反。一般while循环优于until循环。
until [ expression ];do
command1
command2
...
commandN
done
跳出循环:
break 终止循环
continue 跳过当前判断分支的循环
【函数】
用于定义函数的关键字 function 可以忽略不写。
函数返回值必须是整数,一般来说,执行成功返回 0,否则返回非零值。若没有显示地写出 return 语句,最后一条命令的运行结果将作为返回值返回。
变量 $? 表示函数返回值。
变量 $1 表示函数的第 1 个参数,变量 ${10} 表示函数的第 10 个参数。最好使用 花括号{} 将序号括起来。
变量 $# 表示传入函数的参数个数。
function function_name () {
command1
command2
...
commandN
[return value]
}
【文件包含】
命令 . filename 和 source filename 都可以对外部脚本进行包含。注意,小数点符号. 和 filename 之间是使用空格隔开的。
作用相当于 C 中的 #include。用于使用文件 filename 中的变量和函数。
以 #!/bin/[解释器类型] 作为脚本内容的第一行。
比如使用的解释器为 bash,那么第一行就写 #!/bin/bash。同理,若解释器为 sh 就写 #!/bin/sh
如果脚本首行没有这句话,shell 的默认脚本解释器又不是你想用的解释器,那么执行脚本可能会出错。
脚本文件的后缀为 .sh。扩展名只是为了让用户更容易区分文件,没有扩展名的脚本也能运行。
执行脚本前要先使用命令 chmod +x filename.sh 为脚本添加可执行权限。
【注释】
使用 # 作为注释符号。没有多行注释,只能每一行加一个 # 号。
【变量】
分为 局部变量、环境变量、shell变量 3种。
一般变量:
variable_name=variable_value 声明变量或对变量赋值。 等号两侧不能有空格。
variable_name=`command` 将命令 command 的执行结果赋值给变量 variable_name。 符号 ` 是反引号,位于 Esc 键下方。
read variable_name 从 stdin 获取输入并赋值给 variable_name 变量
readonly variable_name 这条命令可以将变量 variable_name 设置为只读。
unset variable_name 删除变量 variable_name
特殊变量:
\$\$ 当前 shell 进程的PID。使用: echo \$\$(斜杠\ 在这里只用于转义,实际使用时应该只有 2 个美元符号而不输入斜杠)
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。$1 表示第一个参数,$2 表示第二个参数。
$# 传递给脚本或函数的参数个数
$* 传递给脚本或函数的所有参数。"$*"会将所有传入参数视为一个字符串。
$@ 传递给脚本或函数的所有参数。"$@"会将传入参数视为不同的字符串。$* 和 $@ 含义相同。注意有没有使用引号""的区别。
$? 上个命令的退出状态,或函数的返回值。一般命令执行成功返回0,否则返回非零值。
使用变量时要在变量名前加$,并且变量可以在引号中使用。例如 echo "Welcome, $name."
为了避免混淆,可以使用花括号将变量括起来。例如 echo "There are 2 ${animal}s."。
变量替换:
${var:-word} 如果变量 var 为空或已被删除,那么返回 word,但不改变 var 的值。
${var:=word} 如果变量 var 为空或已被删除,那么返回 word,并将 var 的值设置为 word。
${var:?message} 如果变量 var 为空或已被删除,那么将 message 输出到标准错误输出,并终止脚本运行。
${var:+word} 如果变量 var 已被定义,那么返回 word,但不改变 var 的值。
数组:
bash只支持一维数组,下标从 0 开始,没有长度限制。使用括号表示数组,使用空格隔开数组元素。
命令 array_name=(value0 value1 value2 ... valueN) 或者
命令 array_name=(
value0
value1
...
valueN
)
均可用于声明并定义一个数组。
array_name[N] 用于操作某个数组元素。
${array_name[N]} 表示某个数组元素的值。
array_name[*] 或 array_name[@] 表示数组中的所有元素。
${array_name[*]} 或 ${array_name[@]} 表示数组中所有元素的值。
${#array_name[*]} 或 ${#array_name[@]} 表示数组元素的个数。
${#array_name[N]} 表示某个数组元素的长度。
【数据输出】
echo -e "hello world!\n" 将输出 hello world![回车]。参数 -e 的功能是开启转义。
echo "hello world!\n" 将输出 hello world!\n。默认不进行转义。
printf "%d %s \n" 1949 "China" 将输出 1949 China[回车]。
用法与 C中 printf() 类似,区别在于调用时不必使用括号,传入的实参用空格隔开且格式化字符串可以重用。比如:
printf "%s %s %s\n" a b c d e f g h i j 的打印结果为:
a b c
d e f
g h i
j
command > /dev/null 2>&1 屏蔽标准输出stdout 和标准错误输出stderr
【数据输入】
read variable_name 从 stdin 读取数据存入变量 variable_name 中
【运算】
数值运算:
使用命令 expr 作为中介实现数值运算。
比如 val=`expr 2 + 2`;echo -e "Total value is: %{val}\n"
需要注意的是运算符和运算数之间必须用空格隔开,写成 2+2 是错误的。
乘法运算符 * 在使用时需要进行转义。比如 val=`expr $input \* 5`
逻辑运算:
常见于 if条件语句的判断语句中
== 数值相等,if[ $a == $b ];then
!= 数值不等,或字符串不同
-eq 数值相等
-ne 数值不等,if[ $c -ne $d ];then
-gt 数值大于
-ge 数值大于等于
-lt 数值小于
-le 数值小于等于
! 非,if[ !$val ];then
-o 或,if[ $a -gt 20 -o $b -gt 20 ];then
-a 且,if[ $c -eq 0 -a $d -le 100 ];then
= 字符串相同,if[ $str1 = $str2 ]
-z 字符串长度为零,if[ -z $str ]
-n 字符串长度不为零,if[ -n $str ]
str 字符串str是否为空,if[ str ]
-e 检测文件或目录是否存在,if[ -e $filedir ]
-s 检测文件是否为空
-b 检测文件是否为块设备文件
-c 检测文件是否为字符设备文件
-d 检测文件是否为目录
-f 检测文件是否是普通文件
-r 检测文件是否可读
-w 检测文件是否可写
-x 检测文件是否可执行
-g 检测文件是否设置了 SGID 位
-u 检测文件是否设置了 SUID 位
-k 检测文件是否设置了粘着位(Sticky Bit)
-p 检测文件是否是具名管道
字符串操作:
string="abcdefg"
echo ${#string} # 获取字符串 string 长度,输出 7
echo ${string:1:4} # 提取子字符串,输出 bcde
echo `expr index "$string" ef` # 查找子字符串 ef 在 $string 中的位置
【流程控制】
退出脚本:
exit NUM 退出脚本,并将状态号置为 NUM
条件语句:
需要注意的是在判断语句后,在 then 之前需要写分号; 才能将 if 和 then 写成 1 行,否则应该分成 2 行写。
判断语句使用 中括号[] 括起来,且表达式 expression 和 中括号[] 之间必须用空格隔开,否则会出现语法错误。
if [ expression ] ; then
....
elif [ expression ] ; then
....
else
....
fi
选择语句:
case VALUE in
value 1)
command1
;; # 两个分号,类似于 C 中的 break
value 2)
command2
;;
*) # 类似于 C 中的 default
commandDefault
;;
esac
for循环语句:
循环语句的执行范围 LIST 是一组值组成的序列,如数字序列、字符串、文件集合等,并且序列中的每个值用空格分隔。
for VAR in LIST;do
command1
command2
...
commandN
done
while循环语句:
while [ expression ];do
command1
command2
...
commandN
done
until循环语句:
until循环与while循环再处理方式上刚好相反。一般while循环优于until循环。
until [ expression ];do
command1
command2
...
commandN
done
跳出循环:
break 终止循环
continue 跳过当前判断分支的循环
【函数】
用于定义函数的关键字 function 可以忽略不写。
函数返回值必须是整数,一般来说,执行成功返回 0,否则返回非零值。若没有显示地写出 return 语句,最后一条命令的运行结果将作为返回值返回。
变量 $? 表示函数返回值。
变量 $1 表示函数的第 1 个参数,变量 ${10} 表示函数的第 10 个参数。最好使用 花括号{} 将序号括起来。
变量 $# 表示传入函数的参数个数。
function function_name () {
command1
command2
...
commandN
[return value]
}
【文件包含】
命令 . filename 和 source filename 都可以对外部脚本进行包含。注意,小数点符号. 和 filename 之间是使用空格隔开的。
作用相当于 C 中的 #include。用于使用文件 filename 中的变量和函数。