与 `bash -c` 命令混淆 - 不适用于全局变量
Confused with `bash -c` command - does not work with global variables
我有两个 shell 命令,实际上是相同的片段,将它们粘贴到终端时:
这个有效:
while true; do \
sleep 1; \
ping -c 1 'www.google.com'; echo $?; \
if [ $? -eq 0 ]; then break; fi; \
done
这不是:
/bin/bash -c "(while true; do \
sleep 1; \
ping -c 1 'www.google.com'; \
if [ $? -eq 0 ]; then break; fi; \
done); \
exit 0"
第二个命令告诉我退出状态为 130
(在 if 执行的行中)即使 ping 执行良好所以退出状态应该为 0。
就像我传递给/bin/bash -c
的字符串中的命令没有在全局变量$?
中注册最后一个退出值。有什么办法可以实现吗?
提前致谢
在 bash -c
解释字符串中的命令之前,您的双引号字符串被展开,因此 $?
可能是前一个命令的退出代码。
您可以通过一个示例来了解这一点,我们还使用 -x
标志来查看幕后情况:
$ set -x
$ bash -c "v=5; echo $v"
+ bash -c 'v=3; echo '
您可以看到当执行到该行时没有要回显的 $v
值,因为 $v
在命令被 bash -c
解释之前已经被替换。
进一步到期;要获得与您的问题几乎相同的输出,请执行以下操作:
- 运行
cat
没有参数和 ctrl+c 中断。
- 运行
bash -c "echo 'hi'; echo $?"
你应该得到 hi
和 130
作为输出,这是你的 sigint'd cat
命令的退出代码。 (请注意,这不是您所期望的 echo "hi"
的出口 0
)。
感谢您的命令,您只需换掉引号即可避免此问题:
/bin/bash -c '(while true; do \
sleep 1; \
ping -c 1 "www.google.com"; \
if [ $? -eq 0 ]; then break; fi; \
done); \
exit 0'
我有两个 shell 命令,实际上是相同的片段,将它们粘贴到终端时:
这个有效:
while true; do \
sleep 1; \
ping -c 1 'www.google.com'; echo $?; \
if [ $? -eq 0 ]; then break; fi; \
done
这不是:
/bin/bash -c "(while true; do \
sleep 1; \
ping -c 1 'www.google.com'; \
if [ $? -eq 0 ]; then break; fi; \
done); \
exit 0"
第二个命令告诉我退出状态为 130
(在 if 执行的行中)即使 ping 执行良好所以退出状态应该为 0。
就像我传递给/bin/bash -c
的字符串中的命令没有在全局变量$?
中注册最后一个退出值。有什么办法可以实现吗?
提前致谢
在 bash -c
解释字符串中的命令之前,您的双引号字符串被展开,因此 $?
可能是前一个命令的退出代码。
您可以通过一个示例来了解这一点,我们还使用 -x
标志来查看幕后情况:
$ set -x
$ bash -c "v=5; echo $v"
+ bash -c 'v=3; echo '
您可以看到当执行到该行时没有要回显的 $v
值,因为 $v
在命令被 bash -c
解释之前已经被替换。
进一步到期;要获得与您的问题几乎相同的输出,请执行以下操作:
- 运行
cat
没有参数和 ctrl+c 中断。 - 运行
bash -c "echo 'hi'; echo $?"
你应该得到 hi
和 130
作为输出,这是你的 sigint'd cat
命令的退出代码。 (请注意,这不是您所期望的 echo "hi"
的出口 0
)。
感谢您的命令,您只需换掉引号即可避免此问题:
/bin/bash -c '(while true; do \
sleep 1; \
ping -c 1 "www.google.com"; \
if [ $? -eq 0 ]; then break; fi; \
done); \
exit 0'