Shell脚本学习
如何抒写一个shell脚本
shell脚本的命名
名字要有意义,最好不要用a、b、c、1、2、3这种方式命名;虽然Linux系统中,文件没有扩展名的概念,依然建议你用.sh结尾;名字不要太长,最好能在30个字节以内解决。
shell脚本格式
shell脚本开头必须指定脚本运行环境以#!这个特殊符号组合来组成。如:#!/bin/bash指定该脚本是运行解析由/bin/bash来完成的
如何运行一个shell脚本
脚本运行需要执行权限,当我们给一个文件赋予执行权限后,该脚本就可以运行
chmod u+x filename
如果不希望赋予脚本执行权限,那么可以使用bash命令来运行未给予执行权限的脚本
bash filename
shell中的特殊符号
符号 | 含义 | |
---|---|---|
~ | 家目录 | cd~代表进入用户家目录 |
!! | 执行历史命令 | !!执行上一条命令 |
$ | 变量中取内容符 | |
+ - * % | 数学运算 | 加 减 乘 除 取余 |
& | 后台执行 | |
* | 通配符 | 匹配所有 |
? | 通配符 | 匹配除回车以外的一个字符 |
; | 分号可以在shell中一行执行多个命令,命令之间用分号分割 | |
丨 | 管道符 | 上一个命令的输出作为下一个命令的输入 |
| | 转义字符 | |
`` | 反引号 命令中执行命令 | echo "today is date +%F " |
’ ’ | 单引号 | 脚本中字符串要用单引号,但是不同于双引号的是,单引号不解释变量 |
" " | 双引号 | 脚本中出现的字符串可以用双引号引起来 |
重定向
重新指定命令执行时I/O设备的方向
-不使用默认的键盘、显示器
-改用指定的文本文件
重定向的类型
根据I/O方向和类别区分
类型 | 操作符 | 用途 |
---|---|---|
重定向输入 | < | 将文本输入来源由键盘改为指定的文件 |
重定向输出 | >和>> | 将命令行的正常执行输出保存到文件,而不是直接显示在屏幕上,>>与>类似,但操作是追加而不是覆盖 |
重定向错误 | 2>和2>> | 将命令行的执行错误信息保存到文件,而不是直接显示在屏幕上,2>>和2>类似,但操作是追加而不是覆盖 |
混合重定向 | &> | 相当于>和2>,覆盖到同一个文件 |
shell传递参数
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
另外,还有几个特殊字符用来处理参数:
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$ *相同,但是使用时加引号,并在引号中返回每个参数。如"$ @“用「”」括起来的情况、以"$ 1" “$ 2” … “$n” 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true | [ $a -eq $b ] 返回 false |
-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 |
布尔运算符
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 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 |
echo命令
Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出
1.显示普通字符串
echo “It is a test”
结果:echo It is a test
2.显示转义字符
echo ““It is a test””
结果:“It is a test”
3.显示变量
a=123
echo $a
结果:123
4.显示换行
echo -e “OK! \n” # -e 开启转义
echo “It is a test”
结果:
OK!
It is a test
5.显示不换行
echo -e “OK! \c” # -e 开启转义 \c 不换行
echo “It is a test”
结果:OK! It is a test
6.显示结果定向至文件
echo “It is a test” > myfile
7.原样输出字符串,不进行转义或取变量(用单引号)
echo ‘$ name"’
结果:$name"
Shell流程控制
if else
fi
if 语句语法格式:
if condition
then
command1
command2
...
commandN
fi
末尾的 fi 就是 if 倒过来拼写
if else
if else 语法格式:
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else
if else-if else 语法格式:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
以下实例判断两个变量是否相等:
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
输出结果:a 小于 b
for循环
for循环一般格式为:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
实例
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
输出结果:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
顺序输出字符串中的字符:
#!/bin/bash
for str in This is a string
do
echo $str
done
输出结果:
This
is
a
string
while 语句
while 循环用于不断执行一系列命令,也用于从输入文件中读取数据。其语法格式为:
while condition
do
command
done
以下是一个基本的 while 循环,测试条件是:如果 int 小于等于 5,那么条件返回真。int 从 1 开始,每次循环处理时,int 加 1。运行上述脚本,返回数字 1 到 5,然后终止。
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
运行脚本,输出:
1
2
3
4
5
无限循环
无限循环语法格式:
while :
do
command
done
或者
while true
do
command
done
或者
for (( ; ; ))
until 循环
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
until 语法格式:
until condition
do
command
done
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
以下实例我们使用 until 命令来输出 0 ~ 9 的数字:
实例:
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
运行结果:
0
1
2
3
4
5
6
7
8
9
case … esac
case … esac 为多选择语句,与其他语言中的 switch … case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。
可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
case … esac 语法格式如下:
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
下面的脚本提示输入 1 到 4,与每一种模式进行匹配:
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
输入不同的内容,会有不同的结果,例如:
输入 1 到 4 之间的数字:
你输入的数字为:
3
你选择了 3
break命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
执行以上代码,输出结果为:
输入 1 到 5 之间的数字:3
你输入的数字为 3!
输入 1 到 5 之间的数字:7
你输入的数字不是 1 到 5 之间的! 游戏结束
continue命令
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
对上面的例子进行修改:
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
运行代码发现,当输入大于5的数字时,该例中的循环不会结束,语句 echo “游戏结束” 永远不会被执行。