变量
- 定义变量变量和等号之间不能有空格, 变量定以后可从新被定义。
variableNumber=100
variableName="value"
variableName="othervalue"
使用readonly可将变量定义为只读变量,只读变量的值不能被改变
url="baidu.com"
readonly url
url="google.com" # ./test.sh: line 4: url: readonly variable
- 使用变量时要在变量前面加美元符号($)
name="yjzhang"
echo $name
echo ${name}
变量名外的花括号可加可不加,目的是告诉解释器识别变量的边界,通常加上。
- 删除变量时用
unset variable_name
,变量删除后不能再使用,unset不能删除只读变量 - 某些字符的变量有特殊含义,这样的变量被称为特殊变量
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数,n是一个数字,表示第几个参数,例如,第一个参数是$1,第二个参数是$2 |
$# | 传递给脚本或函数的参数个数 |
$@ | 传递给脚本或函数的所有参数。被双引号("")包含时,与$*稍有不同,下面将会讲到。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前shell进程ID,对于shell脚本,就是这些脚本所在的进程ID。 |
- 如果表达式中包含特殊字符,shell会进行替换。
a=10
echo -e "value of a is $a \n" # value of is 10
这里的-e表示对转义字符进行替换,如果不适用-e则会原样输出。echo的命令-E选项禁止转义,默认也是不转义的,使用-n宣扬可以禁止插入换行符。
- `command`命令替换是指shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。
- 变量替换可以根据变量的状态(是否为空,是否定义等)来改变他的值
形式 | 说明 |
---|---|
${var} | 变量本来的值 |
${var:-word} | 如果变量var为空或已被删除,那么返回word,但不改变var的值。 |
${var:=word} | 如果变量var为空或已被删除(unset),那么返回word,并将var的值设置为word。 |
${var:?message} | 如果变量var为空或已被删除(unset),那么将消息message送到标准错误输出,可以用来检测变量var是否可以被正常赋值。若此替换出现在shell脚本中,那么脚本将停止运行。 |
${var:+word} | 如果变量var被定义,那么返回word,但不改变var的值。 |
运算符
- 算术运算符,原生bash不支持简单的数学运算,可以使用expr来实现。
a=10
b=20
val=`expr $a + $b`
echo "value: $val"
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 |
expr $a + $b 结果为 30。 |
- | 减法 |
expr $a - $b 结果为 10。 |
* | 乘法 |
expr $a \* $b 结果为 200。 |
/ | 除法 |
expr $b / $a 结果为 2。 |
% | 取余 |
expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等,用于比较两个数字,相同返回true | [ $a == $b ] 返回 false。 |
!= | 不相等,用于比较两个数字,不相同则返回true | [ $a != $b ] 返回 true。 |
表达式和运算符之间要有空格。条件表达式要放在方括号之间,并且要有空格,例如[$a==$b]是错误的,必须写成[ $a = $b ]。
- 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 true。 |
-ne | 检测两个数是否相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
- 布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
- 字符串运算符
a="abc"
b="efg"
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -z $a ] 返回 true。 |
-str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
字符串
- 字符串可用单引号,双引号,还可以不用引号
str='this is a string'
name='yjzhang'
str="hello, \"$name\"! \n"
echo str # hello, yjzhang!
- 单引号里的任何字符串都会原样输出,单引号字符串中的变量是无效的,
单引号字符串中不能出现单引号(对单引号使用转义符后也不行)- 双引号可以有变量
双引号里可以出现转义字符
- 拼接字符串
name="yjzhang"
test="hello, "name" !"
test_1="hello, ${name} !"
echo $test $test_1
- 获取字符串长度
str="abcd"
echo ${#str} # 输出 4
- 提取子字符串
str="Today the weather was good"
echo ${str:1:4} # 输出 oday
- 查找子字符串
str="Today the weather was good"
echo `expr index "$str" is`
数组
- 定义数组时数组元素可以用“空格”符隔开,也可以单独定义数组元素。
array=(value0 value1 value2)
#或者
array1=(
value0
value1
vlaue2
)
# 或者
array2[0]=value0
array2[1]=value1
array2[2]=vlaue2
读取元素的一般格式是:
${array[index]}
,使用@或*可以获取数组中的所有元素${array[*]}
或${array[@]}
获取数组长度的方法与获取字符串长度的方法相同
# 取得数组元素的个数
length=${#array{@}}
#或者
length=${#array{*}}
# 取得数组单个元素的长度
lengthn=${#array[n]}
关系运算
- if else 语句
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
fi # if ... fi
# 最后必须以fi来结尾闭合,fi就是if倒过来拼写。
if [ $a == $b ]
then
echo "a is equal to b"
else
echo "a is not equal to b"
fi # if ... else ... fi
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi # if ... elif ... fi
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo 'The two numbers are equal!'
else
echo 'The two numbers are not equal!'
fi
# if ... else 语句可以与test命令结合使用,test命令用于检查某个条件是否成立,与方括号([])类似。
if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
# if ... else 语句也可以写成一行,以命令的形式运行
- case esac语句
case 值 in # case in 关键字
模式1) # 每个模式必须以右括号结束
command1
command2
command3
;; # ;; 相当于break
模式2)
command1
command2
command3
;;
*) # 如果没有匹配的模式,使用*捕获该值
command1
command2
command3
;;
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'
;;
3) echo 'You select 3'
;;
4) echo 'You select 4'
;;
*) echo 'You do not select a number between 1 to 4'
;;
esac
- for循环
for 变量 in 列表 # 列表是一组值(数字,字符串等)组成的序列,每个值通过空格分隔。
do
command1
command2
...
commandN
done
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
for str in 'This is a string' # 顺序输出字符串中的字符
do
echo $str
done
# 显示主目录下以.bash开头的文件
for FILE in $HOME/.bash*
do
echo $FILE
done
- while循环
while command
do
Statement(s) to be executed if command is true
done
COUNTER=0
while [ $COUNTER -lt 5 ]
do
COUNTER='expr $COUNTER+1'
echo $COUNTER
done
# 用于读取键盘信息,直到按<Ctrl-D>结束循环
echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while read FILM
do
echo "Yeah! great film the $FILM"
done
- until循环
until循环执行一系列=命令直至条件为true时停止,until循环与while循环在处理方式上刚好相反。
until command
do
Statement(s) to be executed until command is true
done
- break和continue命令
break命令可以跳出所有循环
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5, game is over!"
break
;;
esac
done
break n
n是个整数,表示跳出第几层循环。
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
continue只是跳出当前循环
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5!"
continue
echo "Game is over!"
;;
esac
done
continue后面也可以跟一个数字,表示跳出第几层循环。
NUMS="1 2 3 4 5 6 7"
for NUM in $NUMS
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "Number is an even number!!"
continue
fi
echo "Found odd number"
done
函数
- 函数的基本格式
function_name () {
list of commands
[ return value ]
}
函数的返回值可以显示增加return语句,如果不加。会将最后一条命令运行结果作为返回值。
函数返回值只能是赠书,一般用来表示函数是否执行成功,0表示成功,其他表示失败。
如果一定要返回字符串,可以先定义一个变量,用来接收函数的计算结果。
funWithReturn(){
echo "The function is to get the sum of two numbers..."
echo -n "Input first number: "
read aNum
echo -n "Input another number: "
read anotherNum
echo "The two numbers are $aNum and $anotherNum !"
return $(($aNum+$anotherNum))
$?表示函数的返回值
}
funWithReturn # 调用函数只需要给出函数名,不需要加括号
# Capture value returnd by last command
ret=$?
echo "The sum of two numbers is $ret !"
删除函数可以使用unset .f
命令
$unset .f function_name
如果想要直接从终端调用函数,可以将函数定义在主目录下的.profile文件,这样每次登录后,在命令提示符后面输入函数名就可以立即调用。
- 函数参数
在函数内部,通过$n的形式来获取参数的值,$1表示第一个参数,$2表示第二个参数。
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
$10不能获取第十个参数,获取第十个参数要用${10},当n>=10时,需要用${n}来获取参数。
输入输出重定向
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
文件包含
包含脚本有两种方式
. filename
source filename
简单起见,一般使用点号(.)