Shell脚本入门
文章目录
Shell脚本(英语:Shell script),又称Shell命令稿、程序化脚本,是一种计算机程序与文本文件,内容由一连串的shell命令组成,经由Unix Shell直译其内容后运作。被当成是一种脚本语言来设计,其运作方式与解释型语言相当,由Unix shell扮演命令行解释器的角色,在读取shell脚本之后,依序运行其中的shell命令,之后输出结果。利用shell脚本可以进行系统管理,文件操作等。
Shell脚本就是一种命令型语言,虽然它没有Python,JavaScript,Php这些脚本语言强大,但它拥有一般编程语言有的:变量,作用域,数据类型,逻辑运算符,条件运算符,函数等。
Shell脚本内可以直接使用Linux命令,通过编写Shell脚本可以帮助我们实现自动化运维。在运维工作中Shell脚本发挥巨大的重要。
例如有一个需求,需要每天凌晨3点将现网数据库做备份,并只保留最近三天的现网数据。只需将需要执行的命令写如Shell脚本并设置一个任务计划,系统就会在凌晨3点时自动执行这个脚本文件。
任何一组重复性的Linux操作都应该写成一个Shell脚本!
Hello World!
1 | ! /bin/bash |
上面代码保存到hw.sh文件中。执行该脚本的方法是:
1 | $ chmod +x hw.sh |
#!
是告诉系统应该用那个解释器执行该脚本。#!
只能在一个脚本的头部,否则会认为是注释,Shell注释的符号是#
。
chmod +x
给脚本添加执行权限。
./hw.sh
告诉系统在执行本目录下下的hw.sh
脚本。如果省略了./
系统会去$PATH
中查找hw.sh
。
变量
1 | name="fynn" #定义一个变量 name |
在Shell脚本中变量命名只能使用:英文字母,数字和下划线。首个字符不能以数字开头。
Shell脚本中" "
双引号内可以使用变量(${xxx}
),''
单引号中无法使用变量。
注意 变量名与=
和值之间不能有空格!
传递参数
我们在执行Shell脚本时可以向其传递参数,完成脚本的执行。在Shell内部默认获取外部参数的格式是:$n
。n
表示数字,1为执行脚本的第一个参数,2为第二个参数,以此类推。(0表示脚本名字)
1 |
|
执行脚本:
1 | $ ./name.sh Fynn Echo SmallMouse |
参数之间用空格隔开。
Shell定义了一些特殊字符用于处理参数
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。如 “$*” 用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
数组
Bash Shell只支持一维数组,初始化时也不需要指定数组大小。数组元素开始下标从0开始。
1 |
|
注意 数组中的值使用空格分隔,变量名与=
和值之间不能有空格。
运算符
Shell脚本支持传统的运算符(算法运算符,关系运算符,布尔运算符,字符串运算符,文件测试运算符),但和其它编程语言不一样的时Shell脚本中一些运算符需要通过表达式完成,而这些表达式是用反引号**`**包裹着。
例如,两个数字相加需要使用命令expr
:
1 | !/bin/bash |
算术运算符
下表列出常用的算法运算符,假定变量a
为10,而b
为20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | 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 ]
。
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 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 |
逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a
为 10,变量 b
为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
or | 逻辑的OR | [[ $a -lt 100 or $b -gt 100 ]] 返回 true |
字符串运算符
下表列出了常用的字符串运算符,假定变量 a
为 “abc”,变量 b
为 “efg”:
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true | [ $a = $b ] 返回 false |
!= | 检测两个字符串是否相等,不相等返回 true | [ $a != $b ] 返回 true |
-z | 检测字符串长度是否为0,为0返回 true | [ -z $a ] 返回 false |
-n | 检测字符串长度是否为0,不为0返回 true | [ -n "$a" ] 返回 true |
str | 检测字符串是否为空,不为空返回 true | [ $a ] 返回 true |
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。 file='/var/www/test.sh'
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true | [ -b $file ] 返回 false |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true | [ -c $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 | 检测文件是否是有名管道,如果是,则返回 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 |
-s file | 检测文件(包括目录)是否存在,如果是,则返回 true | [ -e $file ] 返回 true |
echo命令
echo
是Shell中最常用的命令之一,一般用于在屏幕输出信息。
1 | echo "It is a test" |
printf命令
printf
命令和echo
命令作用一样,但它由POSIX标准所定义拥有更好的移植性。
并且它支持格式化字符串,拥有更灵活的展示效果。printf format-string [arguments...]
- format-string: 为格式控制字符串。 占位符有:
%s
表示字符串,%f
表示浮点数,%d
表示数字 - arguments: 为参数列表
printf
自身不带换行如果需要换行需要在字符串末尾添加\n
,echo
自身带换行每一个echo
会打印在单独一行上。
1 | printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg |
执行脚本,输出结果如下:
1 | 姓名 性别 体重kg |
%-10s
指一个宽度为10个字符,如果字符长度不足10个字符会自动以空格填充。%-4.2f
指格式化小数,其中保留2位小数。
1 | !/bin/bash |
test命令
Shell中的 test
命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
test
类似于[]
。
数值测试
参数 | 说明 |
---|---|
-eq | 等于则为真 |
-ne | 不等于则为真 |
-gt | 大于则为真 |
-ge | 大于等于则为真 |
-lt | 小于则为真 |
-le | 小于等于则为真 |
1 | num1=100 |
代码中的 []
执行基本的算数运算
1 | !/bin/bash |
字符串测试
参数 | 说明 |
---|---|
= | 等于则为真 |
!= | 不相等则为真 |
-z 字符串 | 字符串的长度为零则为真 |
-n 字符串 | 字符串的长度不为零则为真 |
1 | num1="ru1noob" |
流程控制
流程控制是一个编程语言的基础,Shell脚本拥有常用的:if else
,for
,while
。
if else
if
语句有三种状态:if
,if..else
,if else-if else
1 | if |
实例:
1 | a=10 |
for
格式:
1 | for var in item1 item2 ... itemN |
如果是字符串,for会一一读取字符串中的每个字符赋给变量var
。
1 | for loop in 1 2 3 4 5 |
while
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
1 | while condition |
实例:
1 | !/bin/sh |
case
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
1 | case 值 in |
case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
1 | echo '输入 1 到 4 之间的数字:' |
输入不同的内容,会有不同的结果,例如:
1 | 输入 1 到 4 之间的数字: |
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
break命令允许跳出所有循环(终止执行后面的所有循环)。
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
1 | !/bin/bash |
函数
用户可以自定义函数被脚本随意调用。格式:
1 | [ function ] funname [()] |
1 | funWithReturn(){ |
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
函数参数
1 | funWithParam(){ |
注意:$10
不能获取第十个参数,获取第十个参数需要${10}
。当n>=10时,需要使用${n}
来获取参数。
另外,还有几个特殊字符用来处理参数:
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数 |
$- | 显示Shell使用的当前选项,与set命令功能相同 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误 |
输入/输出重定向
大多数 UNIX 系统命令从你的终端接受输入(获取数据的地方)并将所产生的输出(传递数据的终点位置)发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。
重定向命令列表如下:
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file(file是数据最终放置位置,如果file有数据会覆盖调) |
command < file | 将输入重定向到 file(file是获取数据位置) |
command >> file | 将输出以追加的方式重定向到 file(将数据最加到文件末尾) |
n > file | 将文件描述符为 n 的文件重定向到 file |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file |
n >& m | 将输出文件 m 和 n 合并 |
n <& m | 将输入文件 m 和 n 合并 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入 |
参考
作者: Fynn
链接: https://fynn90.github.io/2018/06/14/Shell%E8%84%9A%E6%9C%AC%E5%85%A5%E9%97%A8/
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可