bash 检查在 while 循环中调用的程序的退出代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35411972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:15:09  来源:igfitidea点击:

Check exit code of a program called in a while loop

bashshell

提问by Micha? Trybus

I would like to write a loop in bash which executes until a certain command stops failing (returning non-zero exit code), like so:

我想在 bash 中编写一个循环,该循环会一直执行,直到某个命令停止失败(返回非零退出代码),如下所示:

while ! my_command; do
    # do something
done

But inside this loop I need to check which exit code my_commandreturned, so I tried this:

但是在这个循环中,我需要检查my_command返回的是哪个退出代码,所以我尝试了这个:

while ! my_command; do
    if [ $? -eq 5 ]; then
        echo "Error was 5"
    else
        echo "Error was not 5"
    fi
    # potentially, other code follows...
done

But then the special variable ?becomes 0inside the loop body. The obvious solution is:

但随后特殊变量?就变成0了循环体内部。显而易见的解决方案是:

while true; do
    my_command
    EC=$?
    if [ $EC -eq 0 ]; then
        break
    fi
    some_code_dependent_on_exit_code $EC
done

How can I check the exit code of my_command(called in loop header) inside loop body without rewriting this example using a while trueloop with a break condition as shown above?

如何my_command在不使用while true具有中断条件的循环重写此示例的情况下检查循环体内部(在循环头中调用)的退出代码,如上所示?

回答by chepner

In addition to the well-known whileloop, POSIX provides an untilloop that eliminates the need to negate the exit status of my_command.

除了众所周知的while循环之外,POSIX 还提供了一个until循环,无需否定 的退出状态my_command

# To demonstrate
my_command () { read number; return $number; }

until my_command; do
    if [ $? -eq 5 ]; then
        echo "Error was 5"
    else
        echo "Error was not 5"
    fi
    # potentially, other code follows...
done

回答by F. Hauri

If truecommand hurt your sensibility, you could write:

如果true命令伤害了你的敏感性,你可以写:

while my_command ; ret=$? ; [ $ret -ne 0 ];do
    echo do something with $ret
  done

This could be simplified:

这可以简化:

while my_command ; ((ret=$?)) ;do
    echo do something with $ret
  done

But if you don't need ResultCode, you could simply:

但如果您不需要ResultCode,您可以简单地:

while my_command ; [ $? -ne 0 ];do
    echo Loop on my_command
  done

or

或者

while my_command ; (($?)) ;do
    echo Loop on my_command
  done

But from there you could better use untilas chepner suggest

但从那里你可以更好地使用untilchepner 建议

回答by pjh

You can get the status of a negated command from the PIPESTATUSbuilt-in variable:

您可以从PIPESTATUS内置变量中获取否定命令的状态:

while ! my_command ; do
    some_code_dependent_on_exit_code "${PIPESTATUS[0]}"
done

chepner's solution is better in this case, but PIPESTATUSis sometimes useful for similar problems.

在这种情况下,chepner 的解决方案更好,但PIPESTATUS有时对类似问题很有用。