bash$?在文件头始终为零

bash$?在文件头始终为零,bash,exit-code,Bash,Exit Code,美元?返回最近执行的命令的退出状态。 它在终端中正常运行。 但是,如果我提到$?在文件的开头,它始终返回零,即使我在之前的终端中运行了以非零退出状态结束的命令。 比如说, $ cat foo.txt; echo $? cat: foo.txt: No such file or directory 1 $ cat foo.txt; ./test.sh cat: foo.txt: No such file or directory 0 ,其中test.sh是 #!/bin/bash echo $?

美元?返回最近执行的命令的退出状态。 它在终端中正常运行。 但是,如果我提到$?在文件的开头,它始终返回零,即使我在之前的终端中运行了以非零退出状态结束的命令。 比如说,

$ cat foo.txt; echo $?
cat: foo.txt: No such file or directory
1
$ cat foo.txt; ./test.sh
cat: foo.txt: No such file or directory
0
,其中test.sh是

#!/bin/bash
echo $?
这是正确的行为吗?
(我使用GNUBash,版本4.4.12)。

这是因为一个以
开头的脚本/bin/bash
始终启动新的子shell,并且前一个shell的退出代码丢失。最后一次运行退出代码仅保留在当前实例中,不会传播到子实例

请参见下面的输出。我在
echo$?
之后添加了一个新行
echo$BASHPID
,以打印新shell的当前进程实例(参见
BASHPID
)。正如您所看到的,失败案例中的数字和运行脚本中的数字各不相同

echo $BASHPID; cat nosuchfile; bash script.sh
8080
cat: nosuchfile: No such file or directory
0
9040
您可以从这里看到,
8080
是父shell实例的pid,从中生成了一个pid
9040
的新shell实例来运行脚本

但是,您可以期望在获取脚本时看到您的行为,该脚本在与上面所示相同的shell实例中运行该脚本

echo $BASHPID; cat nosuchfile; source script.sh
8080
cat: nosuchfile: No such file or directory
1
8080
此处退出代码
1
对应于
cat
因无法打开文件而抛出的退出代码

修改的
script.sh

#!/bin/bash
echo $?
# Print current shell process id
echo $BASHPID

这是因为脚本以
#开头/bin/bash
始终启动新的子shell,并且前一个shell的退出代码丢失。最后一次运行退出代码仅保留在当前实例中,不会传播到子实例

请参见下面的输出。我在
echo$?
之后添加了一个新行
echo$BASHPID
,以打印新shell的当前进程实例(参见
BASHPID
)。正如您所看到的,失败案例中的数字和运行脚本中的数字各不相同

echo $BASHPID; cat nosuchfile; bash script.sh
8080
cat: nosuchfile: No such file or directory
0
9040
您可以从这里看到,
8080
是父shell实例的pid,从中生成了一个pid
9040
的新shell实例来运行脚本

但是,您可以期望在获取脚本时看到您的行为,该脚本在与上面所示相同的shell实例中运行该脚本

echo $BASHPID; cat nosuchfile; source script.sh
8080
cat: nosuchfile: No such file or directory
1
8080
此处退出代码
1
对应于
cat
因无法打开文件而抛出的退出代码

修改的
script.sh

#!/bin/bash
echo $?
# Print current shell process id
echo $BASHPID

是的,行为正确,因为test.sh是在shell的一个新实例中打开的。当您运行脚本时,您正在调用一个新的shell,它没有在命令行中设置变量的记录。我想这是因为shebang行。请改为执行此操作/bin/bash cat foo.txt;回声$是,行为正确,因为test.sh是在shell的一个新实例中打开的。当您运行脚本时,您正在调用一个新的shell,它没有在命令行中设置变量的记录。我想这是因为shebang行。请改为执行此操作/bin/bash cat foo.txt;回声$