访问su -m $ USER -c“<cmd>”之外的退出代码


8

以下命令根据故障或不正确打印“0”或“1”,因为我放了$?在“su”命令中。

sudo su -m $USER -c "./shutdown.sh &> /dev/null; echo \$?"

但是,如果我这样做:

sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null"; echo $?

它将始终打印“0”,因为即使命令部分失败,实际的“su”也将始终成功。

知道如何检索子shell的退出代码吗?

Answers:


7

我刚刚解决了几乎完全相同的情况。希望它仍然可以帮助你,如果不是那么可能是其他人。我从su开始,而不是sudo,但由于sudo打算包装一个其他命令,它真的应该传递su的退出代码。如果没有,您也可以在sudo级别上应用下面的修复程序。

就像你注意到的主要问题是su成功地执行了它的命令。然后默认操作是报告它完成没有任何问题,因此它返回退出代码0.它不“知道”命令的非0退出代码是意外的,或者它应该对它执行某些操作。因此,解决方案很简单,就是让su返回它的最后一个命令的退出代码。这样做对我来说

su <user_x> -c '<bunch_of_commands>; exit $?'

如果sudo不好玩,整个命令应该是这样的(我会为你检查这个,但我没有安装sudo)

sudo 'su <user_x> -c \'<bunch_of_commands>; exit $?\'; exit$?'

注意嵌套报价并确保$?没有扩大,所以没有双引号。


2

通过将整个命令分配给变量(使用子shell)来回显命令内的返回值并在外部访问它。

RETVAL=$(sudo su -m $USER -c "./shutdown.sh &> /dev/null; echo \$?")
echo $RETVAL

0

你总是可以使用tmp文件:

$ sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null; echo \$? > /tmp/exit_code"; cat /tmp/exit_code

是的,这就是我现在正在做的事情,但我希望不要依赖tmp文件。
尼克

0

这适用于Zsh / Bash / Bourne shell:

$ sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null"
$ echo $?

我不确定为什么返回代码在单行中要求时不可用,但是当您使用多行执行相同操作时它可用。


这实际上是不正确的。这将始终返回零,因为“su -m $ USER -c <cmd>”将始终成功,即使其中的实际命令不会。
尼克

1
@Nick - 它在这里工作。你的输出是什么?尝试sudo su -m zero2cx -c "/bin/false &> /dev/null"使用您的系统用户名。$?应该是'1'。
零2cx

是的,用我自己的用户名按预期返回“1”。但我正在尝试使用它来通过自己的用户而不是root用户或任何其他用户运行应用程序。
尼克

@Nick - 它应该$ USER=appusername按照你的意愿使用set。不要使用真实的用户名,insread使用您的意图appusername。它应该工作,它对我来说。
零2cx
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.