Shell脚本的创建与执行
创建脚本文件*.sh
使用touch
命令新建test.sh
文件。这里.sh
的后缀名并不是必须的,任何后缀名甚至是无后缀名都可以。
引入shell声明序列
shell脚本需要符合首行she-bang机制,在第一行使用#!
引入shell声明序列。这里#!/bin/bash
是指该脚本默认用bash解释器执行。
同理,如果想用python执行脚本,则可以在首行引入:
为脚本赋予执行权限并执行
新建的脚本无执行权限,需要使用chmod a+x
命令赋予其执行权限。之后使用./test.sh
即可执行脚本。如果将脚本位置加入环境变量,则可以直接输入脚本名称运行而不再需要前面的./
1
2
|
chmod a+x test.sh
./test.sh
|
shell变量
定义变量
变量是用于存储数据值的名称。使用变量名=变量值
即可给变量赋值。其注意点包括:
1
2
3
|
PI=3.14
NAME=Xiaoming
NAME="Xiao ming"
|
使用变量
想要使用一个变量,则直接在前加上美元符号$
即可。
- 变量名外面的花括号可加可不加,如果不加则会匹配
$
后所有字符,直到出现不可用在变量里的字符为止。加上花括号可以界定变量名的边界,在实际使用中建议都加上花括号。
1
2
3
4
5
|
NAME="Xiao ming"
echo Hello,$NAME # 输出 Hello,Xiao ming
echo "Hello,$NAME" # 输出 Hello,Xiao ming
echo "Hello,${NAME}" # 输出 Hello,Xiao ming
echo 'Hello,$NAME' # 输出 Hello,$NAME
|
变量类型
shell中最常见的变量就是字符串和数字,并且以字符串使用最多。
1
2
3
4
5
6
7
8
9
10
|
# 字符串,字符串可以不用引号,也可以用单引号和双引号。其中单引号没法使用变量展开或转义符号
NAME=XiaoMing
# 整数,需要使用declare命令
declare -i my_integer=42
# 数组
my_array=(1 2 3 4 5)
echo ${my_array[0]}
echo $((${my_array[0]}+${my_array[1]})) #$((expr))可以进行数学运算。这里会输出3。
|
此外,shell中还存在一些特殊的变量:
$PATH
:环境变量,包含了操作系统搜索可执行文件的路径。
$0
表示脚本的名称
$1
,$2
,…… :表示传递给脚本的第几个参数。
$#
:表示传递给脚本的参数数量
$?
:表示上一个命令的退出状态等。
Shell参数传递
在执行 Shell 脚本时,可以向脚本传递参数,脚本内获取参数的格式为$n
,其中n代表一个数字,1为执行脚本的第一个参数,2为执行脚本的第二个参数。
1
2
3
4
5
|
#!/bin/bash
echo "第一个参数为$1"
echo "第二个参数为$2"
echo "参数的个数为$#"
echo "将所有的参数作为一个字符串显示:$*"
|
然后运行该脚本:
输出内容如下:
1
2
3
4
|
第一个参数为ABC
第二个参数为123
参数的个数为2
将所有的参数作为一个字符串显示:ABC 123
|
Shell运算符
算数运算符
bash不支持直接的数学运算,但是可以使用expr命令,或$((...))
来实现。使用expr命令时需要用反引号将expr和表达式包裹起来,同时使用乘法符号时要用反斜杠进行转义。
常见的算数运算符如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
a=1
b=2
# 加
echo $(($a + $b))
echo `expr $a + $b`
# 减
echo $(($a - $b))
echo `expr $a - $b`
# 乘
echo $(($a * $b))
echo `expr $a \* $b` # 需要加转义符号
# 除
echo $(($a / $b))
echo `expr $a / $b`
# 取余
echo $(($a % $b))
echo `expr $a % $b`
# 赋值
a=$b
# 判断是否相等
echo $(($a == $b))
echo `expr $a == $b`
# 判断是否不相等
echo $(($a != $b))
echo `expr $a != $b`
|
关系运算符
进行数值比较时,可以使用旧式的 [ expression1 OP expression2 ]
,OP可以为 “小于”-gt
、“大于”-lt
、“大于等于”-ge
、“小于等于”-le
、“相等”-eq
、“不相等”-ne
,也可以使用新式的 ((expression1 OP expression2))
,OP可以为 >
、<
、>=
、<=
、==
、!=
。新式的写法格式更加自然,同时支持更多高级功能。
布尔运算符
常用的布尔运算符包括:“非”!
、“或”-o
、“与”-a
字符串运算符
常用的字符串运算符包括:
=
:检测两个字符串是否相等
!=
:检测两个字符串是否不相等
-z
:检测字符串长度是否为0
-n
:检测字符串长度是否不为0
$
:检测字符串是否不为空
文件测试运算符
最常用的式-e
,检测文件是否存在
Shell的流程控制
条件判断 if … fi
if-elif-else语法格式:
1
2
3
4
5
6
7
|
if [ condition ]; then
command
elif [ condition ]; then
command
else
command
fi
|
其中:
- 任何一个分支都不能为空。如果该分支没有要执行的内容,就不要写这个分支。
- condition与左右方括号之间都必须有一个空格。
- 在单方括号内大于或小于等关系运算符要用
-gt
、-lt
等,不能使用符号。
- 如果使用双括号((…)),则既不用两边空格,也可以直接使用符号。
- 不管使用那种括号,关系运算符两边都必须有一个空格。
1
2
3
4
5
6
7
8
|
age=50
if [ $age -lt 20 ]; then
echo "young"
elif [ $age -lt 60 ]; then
echo "adult"
else
echo "elderly"
fi
|
多选择语句 case … esac
case … esac 的基本语法格式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
case $Var in
pattern1)
command1
command2
...
commandN
;;
pattern2)
command1
command2
...
commandN
;;
esac
|
case
工作方式如上所示,取值后面必须为单词in
,每一模式必须以右括号结束。取值可以为变量或常数,匹配发现取值符合某一模式后,其间所有命令开始执行直至;;
。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号*
捕获该值,再执行后面的命令。
1
2
3
4
5
6
7
8
9
10
11
|
NAME=Xiaoming
case "$NAME" in
"Xiaohong") echo "Welcome_$NAME"
;;
"Xiaogang") echo "Welcome_$NAME"
;;
"Xiaozhao") echo "Welcome_$NAME"
;;
*) echo "You are not on the namelist"
;;
esac
|
for循环
for循环的基本语法如下:
1
2
3
4
5
6
|
for var in item1 item2 ... itemN; do
command1
command2
...
commandN
done
|
此外,continue
可以跳过这一次循环,break
可以跳过所有循环。
一个for循环的例子如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 输出1-1000内的所有素数到prime.txt中
for i in $(seq 1 1000); do
if [ $i -eq 2 ]; then
echo "$i " >> prime.txt
else
for j in $(seq 2 $(($i-1))); do
if [ $(($i % $j)) -ne 0 ]; then
if [ $j -eq $(($i-1)) ]; then
echo $i >> prime.txt
fi
else
break
fi
done
fi
done
|
while和until循环
while 循环用于不断执行一系列命令,也用于从输入文件中读取数据。其语法格式为:
1
2
3
|
while condition; do
command
done
|
在while循环中,只要condition为true就会一直循环。而until 循环正好相反,当condition为false时会一直循环:
1
2
3
|
until condition; do
command
done
|
一个典型例子如下:
1
2
3
4
5
6
7
8
|
# 计算给定数的阶乘
sum=1
i=1
while [ $i -le $1 ]; do
sum=$(($sum*$i))
i=$(($i+1))
done
echo $sum
|
Shell函数
定义函数
shell中函数的定义格式如下:
1
2
3
4
|
function_name(){
action
return int
}
|
return
语句只能返回一个介于 0 到 255 之间的整数,而两个输入数字的和可能超过这个范围。要解决这个问题,可以直接使用echo
输出而不是使用return
。
- 在Shell中,调用函数时可以向其传递参数。在函数体内部,通过
$n
的形式来获取参数的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 计算给定数的阶乘
Fac(){
if [ $1 -gt 25 ]; then
echo "Too Large"
return 0
fi
sum=1
i=1
while [ $i -le $1 ]; do
sum=$(($sum*$i))
i=$(($i+1))
done
echo $sum
return 1
}
|
使用函数
直接使用函数名+参数即可: