51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Shell小笔记(二)

条件测试语句 {#条件测试语句}

基本语法 {#基本语法}

(1) test <条件>

(2) [ <条件> ] 需要注意环境前后要有空格

结果:条件非空的话为 True (真),反之为 False (假)

需要注意,在Shell中,通常情况下0为真,其他数值为假(特殊情况如字符串测试等除外)。

|-----------|-----------------------------| | 1 | test homo ; echo $? |

文件测试 {#文件测试}

配合操作符,可以实现文件或者目录类型的检测。

例如,检测当前路径下的 homo 是不是目录?

|---------------|------------------------------------------------------------------| | 1 2 3 | touch homo test -d homo ; echo $? #或使用[ -d homo];echo $? |

以下是文件测试操作符与相应说明的对应关系

| 操作符 | 说明 | |:-------:|:-------------------:| | -d | 测试是否为目录(Directory) | | -a | 测试目录或文件是否存在(Exist) | | -f | 测试是否为文件(File) | | -r | 测试当前用户是否可读(read) | | -w | 测试当前用户是否可写(write) | | -x | 测试当前用户是否可执行(excute) |

整数测试 {#整数测试}

整数测试通常用于数值之间的运算,在一些逻辑关系的判断中有应用。

例如判断 1+1+5+4 与 1+9+1 是否相等,可以这么写

|-------------|------------------------------------------------------------------| | 1 2 | echo $(( 1 + 1 + 5 + 4 )) -eq $(( 1 + 9 + 1 )) ; echo $? |

以下是关系测试操作符与相应说明的对应关系

| 操作符 | 关系运算符 | 说明 | |:---:|:-----:|:-----------------------:| | -eq | == | 等于(Equal) | | -ne | != | 不等于(Not Equal) | | -gt | > | 大于(Greater Than) | | -lt | < | 小于(Lesser Than) | | -le | <= | 小于或等于(Lesser or Equal) | | -ge | >= | 大于或等于(Greater or Equal) |

字符串测试 {#字符串测试}

字符串测试操作符的作用包括比较字符串是否相同、测试字符串的长度是否为0。

格式为: [字符串1] 操作符 [字符串2]

以下是字符串测试操作符与相应说明的对应关系

| 操作符 | 含义 | |:---:|:-----------------:| | -z | 判断字符串长度是否为 0 | | -n | 判断字符串长度是否为 非0 | | ! | 判断两边字符串是否 不相等 | | = | 判断两边字符串是否 相等 |

逻辑运算符 {#逻辑运算符}

在Shell条件测试中,使用逻辑运算符实现复杂的条件测试,逻辑运算符用于操作两个变量。

格式为: [表达式1] 操作符 [表达式2]

注意: -a-o 放在 [ ] 里面用, &&|| 放在 [ ] 外面用

以下是逻辑运算操作符与相应说明的对应关系

| 操作符 | 含义 | |:---------:|:--:| | -a 或 && | 与 | | -o 或 || | 或 | | ! | 否 |

if条件 {#if条件}

很常见的判断语句,不过要注意Shell中的流程控制不能为空

即如果 else 分支没有语句执行,就不需要写

if单分支 {#if单分支}

|---------------|---------------------------------| | 1 2 3 | if [条件表达式]; then 代码块 fi |

if双分支 {#if双分支}

|---------------------|-------------------------------------------| | 1 2 3 4 5 6 | if [条件表达式] then 代码块1 else 代码块2 fi |

if多分支 {#if多分支}

|---------------------------|-----------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 | if [条件表达式1]; then 代码块1 elif [条件表达式2]; then 代码块2 elif [条件表达式3]; then 代码块3 else 代码块4 fi |

case条件 {#case条件}

程序会获取case语句中的 变量值

  • 如果满足条件表达式1,则执行代码块 1

  • 如果满足条件表达式2,则执行代码块2

  • 如果满足条件表达式3,则执行代码块3

  • 执行到双分号 ;; ,则停止

  • 如果都不满足,则执行 *) 后面的代码块(上面的双分号会被忽略)

    只要满足一个条件表达式就会跳出 case 语句主体,执行 esac 字符后面的命令

|---------------------------------------|-------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 | case 变量值 in 条件表达式1) 代码块1 ;; 条件表达式2) 代码块2 ;; 条件表达式3) 代码块3 ;; *) 无匹配后代码块 esac |

条件表达式的匹配符如下表所示

| 条件表达式 | 说明 | |:---------:|:---------:| | * | 任意字符 | | ? | 任意单个字符 | | [abc] | a、b或c其中之一 | | [a-n] | 从a到n的任一字符 | | | | 多重选择 |

for循环 {#for循环}

语法 {#语法}

当变量值在列表时, for 循环即执行一次所有命令,使用变量名获取列表中的当前取值

in 的取值列表支持替换、字符串和文件名;不用取值列表将使用命令行的位置参数

通常写法

|-----------------|-------------------------------------------| | 1 2 3 4 | for [变量名] in [取值列表] do [循环体] done |

一行写法

|-----------|---------------------------------------------| | 1 | for [变量名] in [取值列表]; do [循环体] done; |

💡提醒:写成一行(在终端直接执行)时,需要记得加 ; 符号。

例子 {#例子}

脚本将读取用户清单文件(格式: [用户名] [密码] ),并对文件的文本内容进行切片处理(例如第一个参数为用户名,第二个参数为密码),据此创建用户并配置好密码。

|---------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 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 33 34 35 36 37 38 39 40 41 | #!/bin/bash #IFS是内部字段分隔符,此处单词间隔 IFS=$ '\n' #判断脚本是否有参 if [ $# -eq 0 ]; then echo "使用方法: ` $0 ` 用户名单文件" exit 0 fi #判断用户名单是否为文件 if [ ! -f $1 ]; then echo "错误:用户名单 $1 不是文件" exit 0 fi #批量创建用户并设置密码 for line in ` cat $1 ` do if [ ${#line} -eq 0 ]; then #获取文本的长度 echo "清单出现空行,跳过创建。" continue fi #从用户名单中切割出用户名 user=` echo " ${line} " | awk '{print $1}' ` #从用户名单中切割出用户密码 pass=` echo " ${line} " | awk '{print $2}' ` #查询用户是否存在 id ${user} &> /dev/null #根据存在与否创建用户并设置密码 if [ $? -eq 0 ]; then echo "提示:用户 ${user} 已经存在!" else #创建用户 useradd ${user} echo "用户 ${user} 已创建完毕!" #通过管道服务为用户设置密码 echo " ${pass} | passwd -stdin ${user} &> /dev/null" if [ $? -eq 0 ]; then echo "用户 ${user} 的密码配置完毕!" fi fi done echo "提示:已通过文件 $1 的用户清单创建用户,并配置密码。" |

while循环 {#while循环}

用于不断执行一系列命令,也用于从输入文件中读取数据

语法 {#语法-1}

常规写法

|-----------------|-------------------------------------| | 1 2 3 4 | while [条件表达式] do [代码块] done |

无限循环

|-----------------|-----------------------------------------------| | 1 2 3 4 | while : #也可写成while true do [循环体] done |

例子 {#例子-1}

|-------------------------|------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 | # !/bin/bash # 读取键盘信息 echo "按下 Crtl和D 退出" echo -n '你想吃啥: ' while read FOOD do echo "老板,来份:${FOOD}~" done |

until循环 {#until循环}

与while循环相反,until 循环则默认执行,直到条件满足 true 时停止

语法 {#语法-2}

如果条件表达式的返回值为 false,则继续执行循环体内的语句,否则跳出循环。

|-----------------|-------------------------------------| | 1 2 3 4 | until [条件表达式] do [循环体] done |

例子 {#例子-2}

|-------------------------|----------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 | # !/bin/bash # 遍历输出0-9 a=0 until [ ! $a -lt 10 ] do echo ${a} a=$[${a}+1] done |

跳出循环 {#跳出循环}

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环。 break 允许跳出所有循环,而 continue 仅跳出当前循环。

赞(0)
未经允许不得转载:工具盒子 » Shell小笔记(二)