1.Hello World
#!/bin/bash
echo "Hello World !"
2.变量
variableName="value" #声,注意=号左右两边不能有空格
#readonly variableName 声明只读变量,不能删,不能改
#unset variable_name 删除变量
echo $variableName #取
特殊变量列表
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是1,第二个参数是1,第二个参数是2,$1,$2,在传递时用空格隔开。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(“ “)包含时,与 $* 稍有不同,下面将会讲到。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前shell得进程id |
3.通配符
- 匹配任意多个字符(包括零个或一个)
- ? 匹配任意一个字符(不包括零个)
- [characters] 匹配任意一个属于characters中的字符
- [!characters] 匹配不在characters中的字符
- [[:class:]] 匹配任意一个属于指定字符类中的字符
4.转义字符
a=10
#加-e
echo -e "Value of a is $a \n"
# 输出 Value of a is 10
echo "Value of a is $a \n"
# 输出 Value of a is 10 \n
转义字符 | 含义 |
---|---|
\\ | 反斜杠 |
\a | 警报,响铃 |
\b | 退格(删除键) |
\f | 换页(FF),将当前位置移到下页开头 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符(tab键) |
\v | 垂直制表符 |
5.命令替换
命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出
语法:command
DATE=`date`
echo "Date is : $DATE"
USERS=`who | wc -l`
echo "Logged in user are : $USERS"
UP=`date ; uptime`
echo "Uptime is : $UP"
输出:
Date is : Mon Dec 9 13:43:24 CST 2019
Logged in user are : 1
Uptime is : Mon Dec 9 13:43:24 CST 2019
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 的值。 |
echo ${var:-"Variable is not set"} # Variable is not set
echo "1 - Value of var is ${var}" # 1 - Value of var is
echo ${var:="Variable is not set"} # Variable is not set
echo "2 - Value of var is ${var}" # 2 - Value of var is Variable is not set
unset var
echo ${var:+"This is default value"} #
echo "3 - Value of var is $var" #3 - Value of var is
var="Prefix"
echo ${var:+"This is default value"} #This is default value
echo "4 - Value of var is $var" #4 - Value of var is Prefix
echo ${var:?"Print this message"} #Prefix
echo "5 - Value of var is ${var}" #5 - Value of var is Prefix
7.算术
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用
val=`expr 2 + 2`
echo "Total value : $val"
# 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.字符串
单引号
str='this is a string'
单引号里的任何字符都会原样输出
单引号字串中不能出现单引号(对单引号使用转义符后也不行)
双引号
your_name='qinjx'
str="Hello, I know your are \"$your_name\"! \n"
双引号里可以有变量
双引号里可以出现转义字符
拼接字符串
your_name="qinjx"
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting"---"$greeting_1
获取字符串长度
string="abcd"
echo ${#string} #输出 4
提取子字符串
string="alibaba is a great company"
echo ${string:1:4} #输出liba
查找子字符串
string="alibaba is a great company"
echo `expr index "$string" is` #3
字符串切割
string="hello,shell,split,test"
array=(${string//,/ })
13.Shell数组
定义:
方式一:
array_name1=(value0 value1 value2 value3)
方式二:
array_name2=(
value0
value1
value2
value3
)
方式三:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
取
NAME[0]="Zara"
NAME[1]="Qadir"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"
使用@ 或 * 可以获取数组中的所有元素,例如:
${array_name[*]}
${array_name[@]}
获取长度
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
14.输出语句
echo
printf
- printf 命令不用加括号
- format-string 可以没有引号,但最好加上,单引号双引号均可。
- arguments 使用空格分隔,不用逗号
printf "%d %s\n" 1 "abc"
1 abc
15.if … else
if [ expression 1 ]
then
Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
Statement(s) to be executed if expression 3 is true
else
Statement(s) to be executed if no expression is true
fi
expression 和方括号([ ])之间必须有空格,否则会有语法错误
# x$2 != "x" 这种写法是为了防止 $2为空时,会报错
if [ x$2 != "x" ]; then
...
else
....
fi
16.case esac命令
echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
read aNum
case $aNum in
1) echo 'You select 1'
;;
2) echo 'You select 2'
;;
*) echo 'You do not select a number between 1 to 4'
;;
esac
1)2)为模式,可以为任何内容,例如:s1)s2)
17.for循环
for 变量 in 列表
do
command1
command2
...
commandN
done
18.while循环
COUNTER=0
while [ $COUNTER -lt 5 ]
do
COUNTER='expr $COUNTER+1'
echo $COUNTER
done
19.until命令
until 循环执行一系列命令直至条件为 true 时停止
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
20.跳出循环
break:也可以为break n 表示跳出第几层,从内向外数,当前为1
continue:也可以为continue n 表示跳出第几层,从内向外数,当前为1
21. Shell函数
function function_name () {
list of commands
[ return value ]
}
或:
function_name () {
list of commands
[ return value ]
}
函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。
如果 return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”。
如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,
脚本在需要的时候访问这个变量来获得函数返回值。
22.Shell函数参数
funWithParam(){
echo "The value of the first parameter is $1 !"
echo "The value of the second parameter is $2 !"
echo "The value of the tenth parameter is $10 !"
echo "The value of the tenth parameter is ${10} !"
echo "The value of the eleventh parameter is ${11} !"
echo "The amount of the parameters is $# !" # 参数个数
echo "The string of the parameters is $* !" # 传递给函数的所有参数
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
23.输入输出重定向
命令的输出输入不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出输入重定向
输出重定向
$ echo "aaa" > file #覆盖
$ echo "aaa" >> file #追加,自动换行
输入重定向
$ echo `< file`
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
$ a=`cd /home/jw1/ 2>&1`
$ echo $a
24.文件包含
. filename #注意.与filename之间有空格
或
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则应该退出。
#!/bin/bash
set -e
command 1
command 2
...
exit 0
28.BASH_SOURCE
BASH_SOURCE是一个数组,不过它的第一个元素是当前脚本的名称。
vim /root/aa.sh
#!/bin/bash
echo ${BASH_SOURCE[0]}
# 通常用于定位一个目录,常与dirname 配合使用
SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")
PROJECT_ROOT="$SCRIPT_ROOT/.."
# sh /root/aa.sh
/root/aa.sh