Loading... 最近在学习shell脚本,shell作为一种解释型的语言,和php的语法方面有相同之处,在执行方面则和python一样,边解释边执行,若程序中有某处错误则在执行到此处之前不会报错。 以下为学习笔记: --- # 一、shell运行环境 ## (一)Linux * 直接使用vi/vim编辑器创建.sh文件; * 赋予shell脚本可执行权限:假设在当前目录下创建了一个名为*test.py*的脚本,则可运行以下命令赋予脚本可执行权限:`chmod +x ./test.sh`; * 运行脚本:输入`./test.sh`命令,其中“./”表示当前目录下,如果不加./系统会从根目录中寻找该文件,找不到就会报错。 ## (二)Windows * 下载Git,官网链接:[https://git-scm.com/](https://git-scm.com/),进入后点击**Downloads**即可: * 安装后桌面会出现Git Bash快捷方式,进入后就可以使用vi/vim命令创建编辑shell脚本,具体操作方式和Linux系统下相同。 * 注:可以再windows系统下任何一个文件夹里单击右键,点击Git Bash Here,此时git bash的初始目录即在该文件夹下。 # 二、shell基本语法 ## (一)指定解释器 shell作为一种开源脚本,具有多种版本的解释器,比如Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、Shell for Root(/sbin/sh)。这篇笔记主要学习bash即Bourne Again Shell的语法,所以需要在shell脚本开头指定shell解释器的位置: ```bash #! /bin/bash #这是注释,以下为程序部分 ``` 使用其他解释器同理。 ## (二)注释 shell注释使用#号,表示单行注释,多行注释可以使用如下语法: ```bash #! /bin/bash #这是一个单行注释 <<EOF 这是一个多行注释, 也可以使用其他符号如:!等 EOF ``` ## (三)变量 以下是shell中关于变量的几点注意事项,预先说明: * 定义变量时,变量名前不需要加’$‘符号; * 变量名和’=‘和值之间不能有空格,这一点和其他编程语言不同,需要注意; * 变量名命名英文字母、数字和下划线,且不能以数字开头; * 变量名不能和bash里的关键字冲突(可在Git Bash中使用help指令查看bash关键字) * 使用变量时需要加’$‘符号,{}可选。  ### 1、设置变量只读 使用**readonly**关键字设置变量只读: ```bash #! /bin/bash myUrl="https://www.google.com" readonly myUrl myUrl="https://www.runoob.com" #运行后会提示/bin/sh: NAME: This variable is read only. ``` ### 2、删除变量 使用**unset**关键字删除变量: ```bash #! /bin/bash unset myUrl echo $myurl #以上实例执行将没有任何输出。 ``` ### 3、字符串 * 字符串可以用''或""包括,区别是''里面的字符串所有内容都会原样输出,""里面的字符串中若是有变量的话会输出变量,而且单引号里面也会**忽略转义字符; * 获取字符串长度可以使用以下格式:`${#var_name}`; * 提取字符串(如提取字符串中第2到第4个字符):`${var_name:1:4`; * 查找子字符串,方法见下: ```bash #! /bin/bash name = 'Ives Sun' echo 'My name is ${name}' echo "My name is ${name}" #输出结果为: #My name is ${name} #My name is Ives echo ${#name} echo ${name:1:4} #输出结果为: #8 #ves echo `expr index "${name}" v` #输出结果为: #2 ``` ### 4、数组 * 在 Shell 中,用括号来表示数组,Bash Shell 只支持一维数组,初始化时不需要定义数组大小,数组元素用"空格"符号分割开,数组元素的下标由 0 开始; * 读取数组元素值的一般格式是:`${ArrayName[index]}`; * 使用 @或* 符号可以获取数组中的所有元素:`${ArrayName[@]}`; * 获取数组长度的方法与获取字符串长度的方法相同:`${#ArrayName[@]}`; ```bash #! /bin/bash myArray=('Ives' 'Andy' 'John' 'Simth') echo ${myArray[@]} echo ${myArray[2]} echo ${#myArray[@]} echo ${#myArray[2]} #输出结果为: #Ives Andy John Simth #John #4 #4 ``` ## (四)基本运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。expr 是一款表达式计算工具,使用它能完成表达式的求值操作。 * 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样; * 完整的表达式要被反引号包含,注意这个字符不是常用的单引号。 * 乘号(*)前边必须加反斜杠\才能实现乘法运算 ```bash #! /bin/bash val=`expr 2 + 2` echo "两数之和为:${val}" #输出结果为: #两数之和为:4 ``` 下面是常用算术运算符: | 运算符 | 说明 | 举例 | | -------- | ----------------------------------------------- | ------------------------------- | | + | 加法 | `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]。 除算术运算符之外还有关系运算符、布尔运算符、逻辑运算符、字符串运算符、文件测试运算符等。详细运算符操作可以参见:[菜鸟教程](https://www.runoob.com/linux/linux-shell-basic-operators.html) 关系运算符: | 运算符 | 说明 | 备注 | | -------- | ------------------------------------------------------- | ------------- | | -eq | 检测两个数是否相等,相等返回 true。 | equal | | -ne | 检测两个数是否不相等,不相等返回 true | not-equal | | -gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | great than | | -lt | 检测左边的数是否小于右边的,如果是,则返回 true | lower than | | -ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | great equal | | -le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | lower equal | 布尔运算符: | 运算符 | 说明 | | | -------- | ----------------------------------------------------- | --- | | ! | 非运算,表达式为 true 则返回 false,否则返回 true。 | | | -o | 或运算,有一个表达式为 true 则返回 true。 | | | -a | 与运算,两个表达式都为 true 才返回 true。 | | 逻辑运算符: | 运算符 | 说明 | 举例 | | -------- | ------------ | ------ | | && | 逻辑的 AND | | | \|\| | 逻辑的 OR | | # 三、shell流程控制 ## (一)if-else结构 在shell中,if-else的语法如所示,若else结构中没有需要执行的语句,就不要写else: ```bash #! /bin/bash #if-else结构如下: #if condition1 #then # code #elif condition2 #then # code #else # code #fi #实例如下: a=10 b=5 if [ $a -lt $b ] then echo "$a is lower than $b" elif [ $a -eq $b ] then echo "$a is equal to $b" else echo "$a is great than $b" fi #输出结果为: ``` 写成一行(适用于终端命令提示符): ```bash if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi ``` ## (二)for循环结构 ```bash #!/bin/bash for str in This is a string do echo $str done #结果为: #This #is #a #string ``` ## (三)while循环结构 ```bash #!/bin/bash int=1 while(( $int<=5 )) do echo $int let "int++" done #let命令,用于执行一条表达式,表达式中变量不需要加$符号, ``` ## (四)until循环 until循环执行一系列命令直到condition为true,语法结构如下: ```bash #! /bin/bash a=0 until [ ! $a -lt 10 ] do echo $a a=`expr $a + 1` done #结果为依次换行打印出0~9 ``` ## (五)case..esac条件选择分支结构 case条件选择结构类似c语言中的switch-case结构,用`;;`表示break: ```bash #! /bin/bash myArray=('Ives' 'Andy' 'Bob' 'Divad') for man in $myArray do case $man in 'Ives') echo 'Hello Ives' ;; 'Andy') echo 'Hello Andy' ;; 'Bob') echo 'BeyBey Bob' ;; 'Divad') echo 'BeyBey Divad' ;; esac done ``` # 五、shell常用关键字 ## 1、continue、break 用法同其他语言 ## 2、read 获取键盘输入 ```bash #! /bin/bash while true: do echo "请输入一个数字:" read num if [ $num -gt 10 ] then break fi done ``` ## 3、 printf 格式化输出命令,具体用法如下: `%s`、` %c`、 `%d`、 `%f `都是格式替代符,`%s` 输出一个字符串,`%d` 整型输出,`%c` 输出一个字符,`%f` 输出实数,以小数形式输出; `%-10s` 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。 `%-4.2f` 指格式化为小数,其中 `.2` 指保留2位小数。 ```bash #! /bin/bash printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 ``` ## 4、test Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试 ```bash #! /bin/bash echo '请输入一个整数:' read a echo '请输入第二个整数:' read b if test $a -gt $b then echo {test $a -gt $b} else echo {test $a -gt $b} fi ``` 字符串测试: | = | 等于则为真 | | ----------- | -------------------------- | | != | 不相等则为真 | | -z 字符串 | 字符串的长度为零则为真 | | -n 字符串 | 字符串的长度不为零则为真 | ```bash #! /bin/bash num1="ru1noob" num2="runoob" if test $num1 = $num2 then echo '两个字符串相等!' else echo '两个字符串不相等!' fi ``` 文件测试: | -e 文件名 | 如果文件存在则为真 | | ----------- | -------------------------------------- | | -r 文件名 | 如果文件存在且可读则为真 | | -w 文件名 | 如果文件存在且可写则为真 | | -x 文件名 | 如果文件存在且可执行则为真 | | -s 文件名 | 如果文件存在且至少有一个字符则为真 | | -d 文件名 | 如果文件存在且为目录则为真 | | -f 文件名 | 如果文件存在且为普通文件则为真 | | -c 文件名 | 如果文件存在且为字符型特殊文件则为真 | | -b 文件名 | 如果文件存在且为块特殊文件则为真 | Shell 还提供了与( `-a` )、或( `-o `)、非(`!`)三个逻辑操作符用于将测试条件连接起来,其优先级为: `!` 最高, `-a` 次之, `-o` 最低 ```bash #! /bin/bash cd /bin if test -e ./notFile -o -e ./bash then echo '至少有一个文件存在!' else echo '两个文件都不存在' fi ``` ## 5、source 文件包含指令,相当于php里面的include,在shell中还可以使用`. filename`来包含外部文件,***注意.和filename之间含有空格*** 最后修改:2021 年 07 月 23 日 04 : 55 PM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付