Bash IF 语句的行为不符合预期

Bash IF 语句的行为不符合预期

我无法理解这个简单的 Bash 脚本的逻辑:

#!/bin/bash

# Check if file is present
which ./vendor/bin/non_existent_file &> /dev/null

printf "Exited with $?\n\n"

if [[ "$?" -eq 1 ]]; then
  echo "Number is One"
else
  echo "Number is not one"
fi

当文件丢失(不存在)时,输出如下:

Exited with 1

Number is not one

当文件存在时,输出如下:

Exited with 0

Number is not one

???

我尝试过的事情:

if [ $? == 1 ]
if [ "$?" == 1 ]
if [[ "$?" == 1 ]]
if [[ $? -eq 1 ]]
if [[ "$?" = "1" ]]
if [[ "$?" == "1" ]]

为什么 IF 语句总是失败?

答案1

which ./vendor/bin/non_existent_file &> /dev/null

这将运行which并设置$?为其退出状态。 (我现在假设这which对你有用。)

printf "Exited with $?\n\n"

这将运行printf,并设置$?为其退出状态。

if [[ "$?" -eq 1 ]]; then

所以测试的是 的退出状态printf

您需要将退出状态保存到临时变量以避免这种情况,例如

which ./vendor/bin/non_existent_file &> /dev/null
ret=$?
printf 'which exited with status %d\n' "$ret"
if [[ $ret -ne 0 ]]; then
    printf "that was a falsy exit status"
fi

虽然which据我所知会搜索PATH指定的可执行文件,但如果您正在查看固定路径,您可能可以[[ -x ./path ]]直接使用来查看该文件是否可执行。如果您正在寻找 中的程序PATH,您可能想看看为什么不用“哪个”呢?那该用什么呢?对于警告和极端情况。

答案2

感谢@Kusalananda 和@SottoVoce 的评论,这一点很清楚:

$?存储上一个命令的结果,其中包括printf.

因此,运行printf "Exited with $?\n\n"更改$?0由于它已成功执行。

最好将执行结果存储在另一个变量中,以防止发生这种混乱。

相关内容