1. 使用 if-then 语句

最基本的结构化命令就是if-then语句。if-then语句有如下格式。

if   command
then
​   commands
fi

或者

if   command; then
​   commands
fi

bash shell 的 if 语句会运行 if 后面的那个命令。如果该命令的退出状态码是 0(该命令成功运行),位于 then 部分的命令就会被执行。如果该命令的退出状态码是其他值, then 部分的命令就不会被执行,bash shell 会继续执行脚本中的下一个命令。fi 语句用来表示 if-then 语句到此结束。

$ cat test1.sh
#!/bin/bash
# testing the if statement
if pwd
then
echo "It worked"
fi
$

执行结果

$ ./test1.sh
/home/Christine
It worked
$

在 then 部分,你可以使用不止一条命令。可以像在脚本中的其他地方一样在这里列出多条命令。bash shell 会将这些命令当成一个块,如果 if 语句行的命令的退出状态值为 0,所有的命令都会被执行;如果 if 语句行的命令的退出状态不为 0,所有的命令都会被跳过。

2. if-then-else 语句

if-then-else 语句在语句中提供了另外一组命令。

if   command
then
​   commands
else
​   commands
fi

当if语句中的命令返回退出状态码 0 时,then 部分中的命令会被执行,这跟普通的 if-then 语句一样。当 if 语句中的命令返回非零退出状态码时,bash shell 会执行 else 部分中的命令。

3. 嵌套 if 语句

elif 使用另一个 if-then 语句延续 else 部分。

if   command1
thencommands
elif    command2
thenmore commands
fi

elif 语句行提供了另一个要测试的命令,这类似于原始的 if 语句行。如果 elif 后命令的退出状态码是 0,则 bash 会执行第二个 then 语句部分的命令。

$ cat test5.sh
#!/bin/bash
# Testing nested ifs - use elif
#
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
thenecho "The user $testuser exists on this system."
#
elif ls -d /home/$testuser
thenecho "The user $testuser does not exist on this system."echo "However, $testuser has a directory."
#
fi
$
$ ./test5.sh
/home/NoSuchUser
The user NoSuchUser does not exist on this system.
However, NoSuchUser has a directory.
$

可以继续将多个 elif 语句串起来,形成一个大的 if-then-elif 嵌套组合。

if   command1
thencommand set 1
elif    command2
thencommand set 2
elif    command3
thencommand set 3
elif     command4
thencommand set 4
fi

每块命令都会根据命令是否会返回退出状态码 0 来执行。记住,bash shell 会依次执行if语句,只有第一个返回退出状态码 0 的语句中的 then 部分会被执行。

4. test 命令

test 命令提供了在 if-then 语句中测试不同条件的途径。如果 test 命令中列出的条件成立,test 命令就会退出并返回退出状态码 0。如果条件不成立,test 命令就会退出并返回非零的退出状态码,这使得 if-then 语句不会再被执行。

test 命令的格式非常简单。

test condition

condition 是 test 命令要测试的一系列参数和值。如果不写 test 命令的 condition 部分,它会以非零的退出状态码退出,并执行 else 语句块。

$ cat test6.sh
#!/bin/bash
# Testing the test command
#
if test
thenecho "No expression returns a True"
elseecho "No expression returns a False"
fi
$
$ ./test6.sh
No expression returns a False
$

当你加入一个条件时,test 命令会测试该条件。例如,可以使用 test 命令确定变量中是否有内容。这只需要一个简单的条件表达式。

$ cat test6.sh
#!/bin/bash
# Testing the test command
#
my_variable="Full"
#
if test $my_variable
thenecho "The $my_variable expression returns a True"
#
elseecho "The $my_variable expression returns a False"
fi
$
$ ./test6.sh
The Full expression returns a True
$

bash shell 提供了另一种条件测试方法,无需在 if-then 语句中声明 test 命令。

if   [ condition ]
then
​   commands
fi

方括号定义了测试条件。注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。

test 命令可以判断三类条件:

  • 数值比较
  • 字符串比较
  • 文件比较

4.1 数值比较

记住,bash shell只能处理整数

比较操作 描述
n1 -eq n2 检查n1是否与n2相等
n1 -ge n2 检查n1是否大于或等于n2
n1 -gt n2 检查n1是否大于n2
n1 -le n2 检查n1是否小于或等于n2
n1 -lt n2 检查n1是否小于n2
n1 -ne n2 检查n1是否不等于n2
$ cat numeric_test.sh
#!/bin/bash
# Using numeric test evaluations
#
value1=10
value2=11
#
if [ $value1 -gt 5 ]
thenecho "The test value $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
thenecho "The values are equal"
elseecho "The values are different"
fi
#
$
#   运行结果
$ ./numeric_test.sh
The test value 10 is greater than 5
The values are different
$

4.2 字符串比较

比较操作 描述
str1 = str2 检查str1是否和str2相同
str1 != str2 检查str1是否和str2不同
str1 < str2 检查str1是否比str2小
str1 > str2 检查str1是否比str2大
-n str1 检查str1的长度是否非0
-z str1 检查str1的长度是否为0
  1. 检查字符串相等性

    $ cat test7.sh
    #!/bin/bash
    # testing string equality
    testuser=rich
    #
    if [ $USER = $testuser ]
    thenecho "Welcome $testuser"
    fi
    $
    $ ./test7.sh
    Welcome rich
    $
    
  2. 字符串大小

    $ cat test10.sh
    #!/bin/bash
    # testing string length
    val1=testing
    val2=''
    #
    if [ -n $val1 ]
    thenecho "The string '$val1' is not empty"
    elseecho "The string '$val1' is empty"
    fi
    #
    if [ -z $val2 ]
    thenecho "The string '$val2' is empty"
    elseecho "The string '$val2' is not empty"
    fi
    #
    if [ -z $val3 ]
    thenecho "The string '$val3' is empty"
    elseecho "The string '$val3' is not empty"
    fi
    $
    $ ./test10.sh
    The string 'testing' is not empty
    The string '' is empty
    The string '' is empty
    $
    

    空的和未初始化的变量会对shell脚本测试造成灾难性的影响。如果不是很确定一个变量的内容,最好在将其用于数值或字符串比较之前先通过-n或-z来测试一下变量是否含有值。

4.3 文件比较

比较 描述
-d file 检查file是否存在并是一个目录
-e file 检查file是否存在
-f file 检查file是否存在并是一个文件
-r file 检查file是否存在并可读
-s file 检查file是否存在并非空
-w file 检查file是否存在并可写
-x file 检查file是否存在并可执行
-O file 检查file是否存在并属当前用户所有
-G file 检查file是否存在并且默认组与当前用户相同
file1 -nt file2 检查file1是否比file2新 (但不会检查文件是否存在)
file1 -ot file2 检查file1是否比file2旧 (但不会检查文件是否存在)
$ cat test11.sh
#!/bin/bash
# Look before you leap
#
jump_directory=/home/arthur
#
if [ -d $jump_directory ]
thenecho "The $jump_directory directory exists"cd $jump_directoryls
elseecho "The $jump_directory directory does not exist"
fi
#
$
$ ./test11.sh
The /home/arthur directory does not exist
$

5. 复合条件测试

if-then语句允许你使用布尔逻辑来组合测试。有两种布尔运算符可用:

  • [ condition1 ] && [ condition2 ]

    两个条件都必须满足

  • [ condition1 ] || [ condition2 ]

    任意一个条件满足

$ cat test22.sh
#!/bin/bash
# testing compound comparisons
#
if [ -d $HOME ] && [ -w $HOME/testing ]
thenecho "The file exists and you can write to it"
elseecho "I cannot write to the file"
fi
$
$ ./test22.sh
I cannot write to the file
$
$ touch $HOME/testing
$
$ ./test22.sh
The file exists and you can write to it
$

6. if-then 高级特性

bash shell 提供了两项可在 if-then 语句中使用的高级特性:

  • 用于数学表达式的双括号
  • 用于高级字符串处理功能的双方括号

6.1 使用双括号

双括号命令允许你在比较过程中使用高级数学表达式。test 命令只能在比较中使用简单的算术操作。

双括号命令的格式如下:

**(( expression ))**

expression 可以是任意的数学赋值或比较表达式,双括号命令符号如下表所示

符号 描述
val++ 后增
val– 后减
++val 先增
–val 先减
! 逻辑求反
~ 位求反
** 幂运算
<< 左位移
>> 右位移
& 位布尔和
| 位布尔或
&& 逻辑和
|| 逻辑或

可以在if语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值。

$ cat test23.sh
#!/bin/bash
# using double parenthesis
#
val1=10
#
if (( $val1 ** 2 > 90 ))
then(( val2 = $val1 ** 2 ))echo "The square of $val1 is $val2"
fi
$
$ ./test23.sh
The square of 10 is 100
$

**注意,不需要将双括号中表达式里的大于号转义。**这是双括号命令提供的另一个高级特性。

6.2 使用双方括号

双方括号命令提供了针对字符串比较的高级特性。双方括号命令的格式如下:

**[[ expression ]]**

双方括号里的 expression 使用了 test 命令中采用的标准字符串比较。但它提供了 test 命令未提供的另一个特性——模式匹配(pattern matching)。

$ cat test24.sh
#!/bin/bash
# using pattern matching
#
if [[ $USER == r* ]]
thenecho "Hello $USER"
elseecho "Sorry, I do not know you"
fi
$
$ ./test24.sh
Hello rich
$

7. case 命令

case 命令会采用列表格式来检查单个变量的多个值:

case variable in
pattern1 | pattern2)    commands1;;
pattern3)               commands2;;
*)                  default commands;;
esac

case 命令会将指定的变量与不同模式进行比较。如果变量和模式是匹配的,那么 shell 会执行为该模式指定的命令。可以通过竖线操作符在一行中分隔出多个模式模式。星号会捕获所有与已知模式不匹配的值。

$ cat test26.sh
#!/bin/bash
# using the case command
#
case $USER in
rich | barbara)echo "Welcome, $USER"echo "Please enjoy your visit";;
testing)echo "Special testing account";;
jessica)echo "Do not forget to log off when you're done";;
*)echo "Sorry, you are not allowed here";;
esac
$
$ ./test26.sh
Welcome, rich
Please enjoy your visit
$

Linux shell 学习笔记(8)— 使用结构化命令(if-then 语句、数值比较、字符串比较、文件比较、case 语句)相关推荐

  1. 第八章 shell学习之循环和结构化命令

    for循环 1. 列表for循环 for variable in {list}  #有些像C++/CLR中的for each do ... done 如: 1. [root@localhost tmp ...

  2. Linux shell 学习笔记(12)— linux 信号、后台运行脚本、作业控制、定时运行任务

    1. 处理信号 1.1 Linux 信号 常见的 Linux 信号如下表所示: 信号 值 描述 1 SIGHUP 挂起进程 2 SIGINT 终止进程 3 SIGQUIT 停止进程 9 SIGKILL ...

  3. Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)

    1. 理解输入和输出 1.1 标准文件描述符 Linux 系统将每个对象当作文件处理.这包括输入和输出进程.Linux 用文件描述符(file descriptor)来标识每个文件对象.文件描述符是一 ...

  4. Linux shell 学习笔记(7)— 构建基本脚本(变量、重定向、管道、状态码)

    1. 使用多个命令 如果要两个命令一起运行,可以把它们放在同一行中,彼此间用分号隔开. $ date ; who Mon Feb 21 15:36:09 EST 2014 Christine tty2 ...

  5. Linux shell 学习笔记(5)— 文件权限(添加、修改、删除用户及创建、修改群组)

    1. Linux的安全性 Linux 安全系统的核心是用户账户.每个能进入 Linux 系统的用户都会被分配唯一的用户账户.用户对系统中各种对象的访问权限取决于他们登录系统时用的账户. 用户权限是通过 ...

  6. Linux shell 学习笔记(4)— linux 环境变量(全局变量、局部变量及变量持久化)

    1. 环境变量概念及分类 bash shell 用一个叫作环境变量(environment variable)的特性来存储有关 shell 会话和工作环境的信息(这也是它们被称作环境变量的原因).这项 ...

  7. Linux shell 学习笔记(3)— shell 父子关系及内建命令

    1. shell 类型 只要用户登录到某个虚拟控制台终端或是在 GUI 中启动终端仿真器,默认的 shell 程序就会开始运行. 默认的交互 shell 会在用户登录某个虚拟控制台终端或在 GUI 中 ...

  8. Linux shell 学习笔记(1)— 文件和目录(查看、创建、复制、软硬链接、重命名及删除操作)

    1. 启动 shell /etc/passwd 文件包含了所有系统用户账户列表以及每个用户的基本配置信息: christine:x:501:501:Christine Bresnahan:/home/ ...

  9. Linux | Shell 学习笔记(二)Shell 流程控制 if、case、for、while| read读取输入 | 函数的使用 | cut、sed、awk、sort命令 +Demo

    文章目录 参考资料 运行环境 一.流程控制 1.1 if 判断 1.2 case 语句 1.3 for 循环 1.4 while 循环 二. read 读取控制台输入 三.函数 3.1 系统函数 ba ...

最新文章

  1. 详解谷歌最强NLP模型BERT(理论+实战)
  2. C++ Primer英文版(第5版)
  3. python中time的用法_python中的计时器timeit的使用方法
  4. git 分支合并到当前
  5. 视频播放的方法Android,详解Android App中使用VideoView来实现视频播放的方法
  6. [导入]php 安全基础 附录B. 函数
  7. WCF简单教程(5) 用IIS做Host
  8. 说一下output子句
  9. android oat如何提取dex文件字节码,Android: 使用oatdump反编译oat文件
  10. 构建实时数据仓库首选,云原生数据仓库AnalyticDB for MySQL技术解密
  11. android html 显示表格边框,tablelayout表格布局详解
  12. oracle 分区字符转换,Oracle 普通表与分区表转换
  13. 本地在线安装mysql_本地安装MySql服务
  14. 数字电子技术基础(十三):时序逻辑电路(状态机)(移位寄存器、计数器、信号发生器)
  15. c#后台如何导出excel到本地_C# 导出 Excel 的各种方法总结
  16. teechart for java_TeeChart控件Java版
  17. ZZNUOJ_C语言1007:鸡兔同笼(完整代码)
  18. Essay-One Piece海贼王每集剧情介绍
  19. 1236: 数的逆转
  20. JAVA守护线程 非守护线程

热门文章

  1. Java Calendar.add()方法的使用,参数含义。指定时间差。
  2. jar包部署shell脚本编写,在服务器上部署jar包,在Linux服务器上部署服务,设置编码格式,设置内存管理
  3. 2022-2028年中国饮水机市场投资分析及前景预测报告
  4. Eclipse的编码
  5. 只有变强大,才能照亮他人
  6. iceberg问题小结
  7. LeetCode简单题之图像渲染
  8. 基于TensorRT优化的Machine Translation
  9. 从C到C++过渡的3个原因
  10. NVIDIA Jarvis:一个GPU加速对话人工智能应用的框架