KSH:IF 条件问题:if test .... then vs if ... then

KSH: IF condition issue: if test .... then vs if ... then

如果我在 .ksh 文件中放置 test 或不放置 test 有什么区别?

if test  -ne 0 ; then ....

if  -ne 0 ; then ....

非常感谢

我实际上认为这是一个重要的问题,因为它突出了 shell 编程中的一些重要规则:

  1. shellreturn中的每个命令都是真 (0) 或假退出代码
  2. shell中的控制结构不需要比较

shellreturn中的每个命令都有一个退出代码

shell 中任何正确编码的命令都将 return 0 表示成功, 和非零失败。虽然成功的方法只有一种,但失败的方法永远不止一种。

示例:

$ no-such-command || echo no $?
ksh[1]: no-such-command: not found [No such file or directory]
no 127
$ 

命令的退出状态被捕获在伪变量 $? 中,并且在您完成另一个命令之前一直可用。

此退出状态用于 if ... then ... fi 等控制结构 或 until ... do ... done.

failing(){ return 2; }
failing &&
    echo "It works" ||
    echo "It failed with exit code $?"

结果

It failed with exit code 2

shell 中的控制结构不需要比较

让我们从最简单的定义开始 if 命令的:

if compound-list
then
    compound-list
fi

有关完整语法,请参阅第 2.9.4 Compound Commands of Shell Command Language of The Open Group Base Specifications 部分。

在关键字 ifthenfi 之间有两部分 代码,名为 compound-list.

对于在脚本中有效的任何代码序列,这是 shorthand。列表的退出状态将等于列表中最后一个命令的退出状态。

两个列表的重要区别在于第一个列表将确定控制流,而第二个列表将在执行时确定整个表达式的退出状态。

结论

任何命令都可以用作 if/then/else/fi 构造中的 test。 因为我们经常想明确地测试事物,所以我们经常使用实际的 test 命令或其派生命令 [ ... ][[ ... ]].

if [[ -n  ]]; then
    echo "'' is a non-empty string"
fi

对于复杂的表达式,最好将它们包装在 应用一些抽象的函数。

再举一个简单的例子:

non_empty_files_present(){
  (path=${1:?directory expected}
    (find ${path} -type f -size +0 | read line) 2> /dev/null
  )
}

if non_empty_files_present /var/tmp; then
  echo "Some files have content"
fi