1.Hello World

  1. #!/bin/bash
  2. echo "Hello World !"

2.变量

  1. variableName="value" #声,注意=号左右两边不能有空格
  2. #readonly variableName 声明只读变量,不能删,不能改
  3. #unset variable_name 删除变量
  4. echo $variableName #取

特殊变量列表

变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是1,第二个参数是1,第二个参数是2,$1,$2,在传递时用空格隔开。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(“ “)包含时,与 $* 稍有不同,下面将会讲到。
$? 上个命令的退出状态,或函数的返回值。
$$ 当前shell得进程id

3.通配符

    •         匹配任意多个字符(包括零个或一个)
  • ?         匹配任意一个字符(不包括零个)
  • [characters]    匹配任意一个属于characters中的字符
  • [!characters]    匹配不在characters中的字符
  • [[:class:]]     匹配任意一个属于指定字符类中的字符

4.转义字符

  1. a=10
  2. #加-e
  3. echo -e "Value of a is $a \n"
  4. # 输出 Value of a is 10
  5. echo "Value of a is $a \n"
  6. # 输出 Value of a is 10 \n
转义字符 含义
\\ 反斜杠
\a 警报,响铃
\b 退格(删除键)
\f 换页(FF),将当前位置移到下页开头
\n 换行
\r 回车
\t 水平制表符(tab键)
\v 垂直制表符

5.命令替换

命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出
语法:command

  1. DATE=`date`
  2. echo "Date is : $DATE"
  3. USERS=`who | wc -l`
  4. echo "Logged in user are : $USERS"
  5. UP=`date ; uptime`
  6. echo "Uptime is : $UP"
  7. 输出:
  8. Date is : Mon Dec 9 13:43:24 CST 2019
  9. Logged in user are : 1
  10. Uptime is : Mon Dec 9 13:43:24 CST 2019
  11. 13:43:24 up 156 days, 19:20, 1 user, load average: 4.01, 3.60, 3.15

6.变量替换

变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值

形式 说明
${var} 变量本来的值
${var:-word} 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
${var:=word} 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
${var:?message} 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。
若此替换出现在Shell脚本中,那么脚本将停止运行。
${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。
  1. echo ${var:-"Variable is not set"} # Variable is not set
  2. echo "1 - Value of var is ${var}" # 1 - Value of var is
  3. echo ${var:="Variable is not set"} # Variable is not set
  4. echo "2 - Value of var is ${var}" # 2 - Value of var is Variable is not set
  5. unset var
  6. echo ${var:+"This is default value"} #
  7. echo "3 - Value of var is $var" #3 - Value of var is
  8. var="Prefix"
  9. echo ${var:+"This is default value"} #This is default value
  10. echo "4 - Value of var is $var" #4 - Value of var is Prefix
  11. echo ${var:?"Print this message"} #Prefix
  12. echo "5 - Value of var is ${var}" #5 - Value of var is Prefix

7.算术

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用

  1. val=`expr 2 + 2`
  2. echo "Total value : $val"
  3. # Total value : 4

注意:

  • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
  • 完整的表达式要被 包含
  • 乘号(*)前边必须加反斜杠()才能实现乘法运算
      • * / != == = %
  • 条件表达式要放在方括号之间,并要有空格,例如 [a==a==b] 是错误的,必须写成 [ a==a==b ]

8.关系运算符

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ a−eqa−eqb ] 返回 true。
-ne 检测两个数是否相等,不相等返回 true。 [ a−nea−neb ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ a−gta−gtb ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ a−lta−ltb ] 返回 true。
-ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ a−gea−geb ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ a−lea−leb ] 返回 true。

9.布尔运算符

运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ a−lt20−oa−lt20−ob -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ a−lt20−aa−lt20−ab -gt 100 ] 返回 false。

10.字符串运算符

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ a=a=b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ a!=a!=b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -z $a ] 返回 true。
str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

11.文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性

操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是具名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。

12.字符串

单引号

  1. str='this is a string'
  2. 单引号里的任何字符都会原样输出
  3. 单引号字串中不能出现单引号(对单引号使用转义符后也不行)

双引号

  1. your_name='qinjx'
  2. str="Hello, I know your are \"$your_name\"! \n"
  3. 双引号里可以有变量
  4. 双引号里可以出现转义字符
  1. 拼接字符串
  2. your_name="qinjx"
  3. greeting="hello, "$your_name" !"
  4. greeting_1="hello, ${your_name} !"
  5. echo $greeting"---"$greeting_1
  6. 获取字符串长度
  7. string="abcd"
  8. echo ${#string} #输出 4
  9. 提取子字符串
  10. string="alibaba is a great company"
  11. echo ${string:1:4} #输出liba
  12. 查找子字符串
  13. string="alibaba is a great company"
  14. echo `expr index "$string" is` #3
  15. 字符串切割
  16. string="hello,shell,split,test"
  17. array=(${string//,/ })

13.Shell数组

定义:

  1. 方式一:
  2. array_name1=(value0 value1 value2 value3)
  3. 方式二:
  4. array_name2=(
  5. value0
  6. value1
  7. value2
  8. value3
  9. )
  10. 方式三:
  11. array_name[0]=value0
  12. array_name[1]=value1
  13. array_name[2]=value2

  1. NAME[0]="Zara"
  2. NAME[1]="Qadir"
  3. echo "First Index: ${NAME[0]}"
  4. echo "Second Index: ${NAME[1]}"
  5. 使用@ * 可以获取数组中的所有元素,例如:
  6. ${array_name[*]}
  7. ${array_name[@]}

获取长度

  1. # 取得数组元素的个数
  2. length=${#array_name[@]}
  3. # 或者
  4. length=${#array_name[*]}
  5. # 取得数组单个元素的长度
  6. lengthn=${#array_name[n]}

14.输出语句

echo
printf

  • printf 命令不用加括号
  • format-string 可以没有引号,但最好加上,单引号双引号均可。
  • arguments 使用空格分隔,不用逗号
    1. printf "%d %s\n" 1 "abc"
    2. 1 abc

15.if … else

  1. if [ expression 1 ]
  2. then
  3. Statement(s) to be executed if expression 1 is true
  4. elif [ expression 2 ]
  5. then
  6. Statement(s) to be executed if expression 2 is true
  7. elif [ expression 3 ]
  8. then
  9. Statement(s) to be executed if expression 3 is true
  10. else
  11. Statement(s) to be executed if no expression is true
  12. fi

expression 和方括号([ ])之间必须有空格,否则会有语法错误

  1. # x$2 != "x" 这种写法是为了防止 $2为空时,会报错
  2. if [ x$2 != "x" ]; then
  3. ...
  4. else
  5. ....
  6. fi

16.case esac命令

  1. echo 'Input a number between 1 to 4'
  2. echo 'Your number is:\c'
  3. read aNum
  4. case $aNum in
  5. 1) echo 'You select 1'
  6. ;;
  7. 2) echo 'You select 2'
  8. ;;
  9. *) echo 'You do not select a number between 1 to 4'
  10. ;;
  11. esac
  12. 1)2)为模式,可以为任何内容,例如:s1)s2)

17.for循环

  1. for 变量 in 列表
  2. do
  3. command1
  4. command2
  5. ...
  6. commandN
  7. done

18.while循环

  1. COUNTER=0
  2. while [ $COUNTER -lt 5 ]
  3. do
  4. COUNTER='expr $COUNTER+1'
  5. echo $COUNTER
  6. done

19.until命令

until 循环执行一系列命令直至条件为 true 时停止

  1. a=0
  2. until [ ! $a -lt 10 ]
  3. do
  4. echo $a
  5. a=`expr $a + 1`
  6. done

20.跳出循环

break:也可以为break n 表示跳出第几层,从内向外数,当前为1
continue:也可以为continue n 表示跳出第几层,从内向外数,当前为1

21. Shell函数

  1. function function_name () {
  2. list of commands
  3. [ return value ]
  4. }
  5. 或:
  6. function_name () {
  7. list of commands
  8. [ return value ]
  9. }
  10. 函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
  11. Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。
  12. 如果 return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”。
  13. 如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,
  14. 脚本在需要的时候访问这个变量来获得函数返回值。

22.Shell函数参数

  1. funWithParam(){
  2. echo "The value of the first parameter is $1 !"
  3. echo "The value of the second parameter is $2 !"
  4. echo "The value of the tenth parameter is $10 !"
  5. echo "The value of the tenth parameter is ${10} !"
  6. echo "The value of the eleventh parameter is ${11} !"
  7. echo "The amount of the parameters is $# !" # 参数个数
  8. echo "The string of the parameters is $* !" # 传递给函数的所有参数
  9. }
  10. funWithParam 1 2 3 4 5 6 7 8 9 34 73

23.输入输出重定向

命令的输出输入不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出输入重定向
输出重定向

  1. $ echo "aaa" > file #覆盖
  2. $ echo "aaa" >> file #追加,自动换行

输入重定向

  1. $ echo `< file`
  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

  1. $ a=`cd /home/jw1/ 2>&1`
  2. $ echo $a

24.文件包含

  1. . filename #注意.与filename之间有空格
  2. source filename

25.执行命令的方式

  • command/$()
  • $(eval “./restart_ice.sh $var” 2>&1)
  • 执行可执行文件
    • 环境变量中的,例如:ps
    • 用./,例如:cd /home && ./start.sh 或 ./home/start.sh
    • 全路径,一定要定位到一个可执行文件,例如:/home/start.sh

26.脚本退出

exit 0:正常运行程序并退出程序;
exit 1:非正常运行导致退出程序;

27.set -e

你写的每个脚本都应该在文件开头加上set -e,这句语句告诉bash如果任何语句的执行结果不是true则应该退出。

  1. #!/bin/bash
  2. set -e
  3. command 1
  4. command 2
  5. ...
  6. exit 0

28.BASH_SOURCE

BASH_SOURCE是一个数组,不过它的第一个元素是当前脚本的名称。

  1. vim /root/aa.sh
  2. #!/bin/bash
  3. echo ${BASH_SOURCE[0]}
  4. # 通常用于定位一个目录,常与dirname 配合使用
  5. SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")
  6. PROJECT_ROOT="$SCRIPT_ROOT/.."
  1. # sh /root/aa.sh
  2. /root/aa.sh