发布于 2026-01-06 7 阅读
0

Shell脚本:条件执行 DEV全球展示挑战赛,由Mux呈现:展示你的项目!

Shell脚本:条件执行

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

图片替代文字

这是Shell脚本系列教程的第二部分。如果您错过了第一部分,可以在这里找到。

另外请注意,大部分代码仅使用bashzshshell 进行过测试,可能无法在其他 shell 上运行。

条件执行意味着您可以选择仅在满足特定条件时才执行代码。如果没有这种能力,您只能依次执行一条又一条命令。能够测试系统状态和进程环境变量的各种信息,意味着 shell 脚本可以执行远比以往更强大的操作。在本文中,我们将探讨test operators条件if/then/else语句case

test又名[

通过测试,我们可以检查例如:文件是否存在、一个数字是否大于另一个数字、比较字符串是否相等……

句法:

[ condition-to-test-for ]
Enter fullscreen mode Exit fullscreen mode

例子:

[ -e /etc/passwd ]
Enter fullscreen mode Exit fullscreen mode

如上文所述,`is` 的另一个名称是test`is` [。它也是一个 shell 内置函数(这意味着即使你的 Unix 环境配置不同, shell 本身也会将其解释[为`is`)。调用 `is` 时,它的参数需要一个 ` is` 关键字,除此之外,它的功能与 `is` 相同。test[]

test  -e /etc/passwd
# as above so below
[ -e /etc/passwd ]
Enter fullscreen mode Exit fullscreen mode

该命令会检查是否etc/passwd存在,如果存在,则返回true命令退出状态0。如果不存在,则命令以退出状态退出1(有关退出状态的更多信息,请参见下一篇文章)。

注意[:运算符和符号之间的空格]是必需的!例如:`
[-e /etc/passwd ]\n` 是行不通的;它会被解释为test-e /etc/passwd ]`\n`,这会报错,因为]`\n` 没有开头[。` [\n` 实际上是一个程序,就像 `\n`ls和其他程序一样,它必须被空格包围。
所以,记住:所有运算符周围都要加上空格。

注意:您可以使用以下命令撤销测试结果!

if [ ! -r$1]; then echo "File $1 is not readable – skipping."; fi
Enter fullscreen mode Exit fullscreen mode

如您所见,test这是一个简单但功能强大的比较工具。要了解完整详情,请man test在您的系统上运行,但以下是一些用法和典型示例:

文件测试运算符:

-d FILE #True if the file is a directory
-e FILE #True if the file exists
-f FILE #True if the file exists and it's regular file
-r FILE #True if the file is readable by you
-s FILE #True if the file exists and it's not empty
-w FILE #True if the file is writable by you
-x FILE #True if the file is executable by you
Enter fullscreen mode Exit fullscreen mode

字符串测试运算符:

-z STRING #True if the string is empty
-n STRING #True if the string is not empty
STRING1 = STRING2 #True if the strings are equal
STRING1 != STRING2 #True if the strings are not equal
Enter fullscreen mode Exit fullscreen mode

算术测试:

arg1 -eq arg2 #True if the arguments are equal
arg1 -ne arg2 #True if the arguments are not equal
arg1 -lt arg2 #True if the arg1 is less than arg2
arg1 -le arg2 #True if arg1 is less than or equal to arg2
arg1 -gt arg2 #True if arg1 is greater than arg2
arg1 -ge arg2 #True if arg1 is greater than or equal to arg2
Enter fullscreen mode Exit fullscreen mode

&&||

可以使用“&&||”运算符组合测试和/或链接多个命令。它们分别执行逻辑与和逻辑或运算。

  • && = AND
    mkdir /tmp/bak && cp test.txt /tmp/bak

    &&只有当上一个命令成功执行(即以退出状态退出)时,才会执行下一个命令0

  • || = OR
    cp test.txt /tmp/bak || cp test.txt /tmp

    ||运算符执行逻辑或运算,因此,当只需要满足其中一个条件,而不需要满足哪个条件时,就可以使用此功能。

#! /bin/bash
HOST="google.com"
ping -c 1 $HOST && echo "$HOST reachable."
Enter fullscreen mode Exit fullscreen mode

如果/那么

几乎所有编程语言都有 if/then/else 结构,Shell 也不例外。其语法使用方括号进行判断,并且必须包含thenandfi语句,其作用类似于 C 和其他一些语言中的花括号 { 和 }。

句法:

if [ condition ]
then
    statements for when the condition is true
fi
Enter fullscreen mode Exit fullscreen mode

除了逗号后的换行符之外,所有这些换行符都是必需的,或者可以用分号代替。再次提醒:逗号和符号then周围的空格也是必需的,所以最好将其简化为(请不要这样做):[]
if [ condition ];then statements;fi

使用分号将 then 和 if 放在同一行是很常见的做法。

例子:

MY_SHELL="zsh"

if [ "$MY_SHELL" = "zsh" ]
    then
        echo "You are the zsh shell user!"
fi
Enter fullscreen mode Exit fullscreen mode

别的

您可能希望尽可能运行该命令,但如果无法运行,则继续执行脚本。一种(更简单也最常用的)方法是使用 ELSE 语句:

if [ condition ]; then
    statements for when the condition is true
else
    statements for when the condition is false
fi
Enter fullscreen mode Exit fullscreen mode
#!/bin/bash

# Check for likely causes of failure
if [ -r "$1" ]; then
    cat "$1"
else
    echo "Error: $1 is not a readable file."
fi
Enter fullscreen mode Exit fullscreen mode

这段代码尝试读取cat作为第一个参数传递给它的文件("$1"用双引号将其括起来,以允许文件名包含空格),如果读取失败,则会输出错误消息。

ELIF

elifelse`else if` 是一种允许你在语句中添加条件的结构if。它是 `else if` 的缩写,这样就可以更简洁地编写一长串可能的操作。这使得代码更易于编写、更易于阅读,最重要的是,更易于调试。

#!/bin/bash 
OS=`uname -s`
if [ "$OS" = "FreeBSD" ]; then
    echo "This Is FreeBSD"
elif [ "$OS" = "CYGWIN_NT-5.1" ]; then
    echo "This is Cygwin"
elif [ "$OS" = "SunOS" ]; then
    echo "This is Solaris"
elif [ "$OS" = "Darwin" ]; then
    echo "This is Mac OSX"
elif [ "$OS" = "Linux" ]; then
    echo "This is Linux"
else
    echo "Failed to identify this OS"
fi
Enter fullscreen mode Exit fullscreen mode

它可能变成的那种嵌套代码地狱易读得多。else


case陈述

case与传统的语句结构相比,`case` 语句提供了一种更简洁、更易写、更易读的替代方案if/then/else,尤其是在需要测试大量可能值的情况下。使用 `case` 语句,您可以列出要识别和处理的值,然后为每个值提供一段代码块。`case`
语句的一个常见应用场景是系统启动脚本。
语法:

case "$VAR" in
    pattern_1)
        # Some commands here.
        ;; # Execution will stop when the double semicolon is reached 
    pattern_n)
        # Some commands here.
        ;;
esac
Enter fullscreen mode Exit fullscreen mode

例子:

#!/bin/bash
OS=`uname -s`

case "$OS" in
    FreeBSD) echo "This is FreeBSD" ;;
    CYGWIN_NT-5.1) echo "This is Cygwin" ;;
    SunOS) echo "This is Solaris" ;;
    Darwin) echo "This is Mac OSX" ;;
    Linux) echo "This is Linux" ;;
    *) echo "Failed to identify this OS" ;;
esac
Enter fullscreen mode Exit fullscreen mode

虽然它看起来像是一个特殊指令,但*实际上它只是最通用的通配符,因为它能匹配任何字符串。这也意味着我们可以进行更高级的模式匹配RegEx,例如 `\n`。

请注意,图案区分大小写。

Bash 实现中一个不太为人所知的特性是,你可以用 `\n`或 ` \n`case结束语句,而不仅仅是 `\n`。` \n`表示不会执行任何其他语句,但如果你用 `\n` 结束语句,所有后续的 `\n` 语句仍然会被执行。如果你用 `\n` 结束语句,则该 `\n` 语句将被视为已匹配到 `\n` 语句。;;&;&;;;;;;&;&

#!/bin/bash

read -p "Give me a word: " input
echo -en "That's "
case $input in
  *[[:digit:]]*) echo -en "numerical " ;;&
  *[[:lower:]]*) echo -en "lowercase " ;;&
  *[[:upper:]]*) echo -en "uppercase " ;;&
  *) echo "input." ;;
esac

$ ./case1.sh
Give me a word: Hello 123
That's numerical lowercase uppercase input.
Enter fullscreen mode Exit fullscreen mode

此功能仅适用于 bash shell;它并非 Bourne shell 的标准功能,因此如果您需要编写可移植的脚本,请不要指望它能正常工作。在其他 shell 中,它会引发语法错误。


本文介绍了控制条件执行的各种方法——从简单的条件语句if/then/else construct,到可以使用条件语句执行的不同操作test,再到更灵活的case语句,用于匹配不同的输入集。

我必须承认,一开始我觉得写关于 shell 编程的文章最多也就两三篇,但实际上内容非常丰富,即使是这篇文章和之前的文章,也只涵盖了我所写主题的一半。如果你想更深入地学习 shell 编程,我强烈推荐《高级 Bash 脚本指南》《经典 Shell 脚本》。下一篇文章我会简单介绍一下位置参数、退出码以及(希望)函数。感谢阅读!

文章来源:https://dev.to/puritanic/shellscripting-conditional-execution-3kgm