39

我写了一个函数:

check_log(){
    if [ -f "/usr/apps/appcheck.log" ]
    then
         return 1
    else
         return 0
    fi
}

然后我在“if”条件下调用这个函数:

if [ check_log ];
then
    ........statements....
fi

这行得通吗?我在这里感到困惑,因为 bash 在成功时返回 0,在失败时返回 1,但是我的函数正在返回1并且条件正在检查1/ 0,它得到1并且应该给出失败,但是在我的 shell 脚本中,条件正在通过。

任何人都可以阐明这个问题吗?

4

2 回答 2

70
if [ check_log ];

当您使用方括号时,您正在调用test命令。它相当于if test check_logwhich 是 的简写if test -n check_log,这又意味着“如果"check_log"不是空字符串”。它根本不调用你的check_log函数。

将其更改为:

if check_log;

顺便说一句,函数可以更简单地写成:

check_log() {
    ! [ -f "/usr/apps/appcheck.log" ]
}

函数的返回值是最后一个命令的退出状态,因此不需要显式的返回语句。

于 2013-03-27T19:55:06.133 回答
2

正如@john-kugelman 所指出的,一种解决方案(也许是最正确的一种)是使用以下语法:

if check_log;

但另一种解决方案是:

if [[ $(check_log; echo $?) -eq 0 ]];

我个人的偏好是后者,因为它促进了条件语句之间的一致性。但缺点是因为它依赖于命令替换,它会派生一个子进程(即子shell),而第一种方法不会。

可以在此处找到有关该主题的有趣阅读:

什么时候命令替换比单独的相同命令产生更多的子shell?

更新(2020-12-01):在大多数情况下,由于效率低下和可能触发错误结果的原因,不建议使用上述替代解决方案,尤其是在被调用函数写入 stderr 或 stdout 并且输出未被捕获的情况下.

更新(2017-10-20):删除我对第二种方法的偏好,因为这些天我的任务是防止不必要的分叉。第一个解决方案中的语法对于非 shell 编程来说并不那么直观,但它肯定更有效。

于 2015-01-28T21:27:16.780 回答