Zugriff auf einen Exit-Code außerhalb eines su -m $ USER -c "<cmd>"


8

Der folgende Befehl gibt "0" oder "1" korrekt aus, je nachdem, ob ein Fehler vorliegt oder nicht, da ich $? innerhalb des Befehls "su".

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

Wenn ich dies jedoch tue:

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

Es wird immer "0" ausgegeben, da das tatsächliche "su" immer erfolgreich ist, selbst wenn der Befehlsteil fehlschlägt.

Irgendeine Idee, wie ich den Exit-Code der Subshell abrufen kann?

Antworten:


7

Ich habe gerade fast genau die gleiche Situation behoben. Hoffe es hilft dir noch, wenn nicht dann vielleicht anderen. Ich habe mit su angefangen, nicht mit sudo, aber da sudo einen einzelnen anderen Befehl umschließen soll, sollte es wirklich den Exit-Code von su weiterleiten. Wenn nicht, können Sie den folgenden Fix auch auf der Sudo-Ebene anwenden.

Wie Sie bereits bemerkt haben, besteht das Hauptproblem darin, dass su den Befehl erfolgreich ausführt. Die Standardaktion besteht dann darin, zu melden, dass der Vorgang ohne Probleme abgeschlossen wurde, und daher den Exit-Code 0 zurückzugeben. Er "weiß" nicht, dass ein Exit-Code ungleich 0 aus einem Befehl unerwartet war oder dass er etwas damit tun sollte. Daher besteht die Lösung ganz einfach darin, su den Exit-Code seines letzten Befehls zurückgeben zu lassen. Das hat es für mich getan

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

Falls sudo nicht gut spielt, sollte der gesamte Befehl ungefähr so ​​aussehen (ich würde dies für Sie überprüfen, aber ich habe sudo nicht installiert).

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

Achten Sie auf die Verschachtelung von Anführungszeichen und stellen Sie sicher, dass $? wird nicht erweitert, also keine doppelten Anführungszeichen.


2

Geben Sie den Rückgabewert innerhalb des Befehls wieder und greifen Sie außerhalb darauf zu, indem Sie den gesamten Befehl einer Variablen zuweisen (mithilfe einer Unterschale).

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

0

Sie können immer eine tmp-Datei verwenden:

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

Ja, das ist es, was ich gerade mache, aber ich hatte gehofft, mich nicht auf eine tmp-Datei verlassen zu können.
Nick

0

Dies funktioniert in Zsh / Bash / Bourne-Shells:

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

Ich bin nicht sicher, warum der Rückkehrcode nicht verfügbar ist, wenn Sie in einem Einzeiler danach fragen, aber er ist verfügbar, wenn Sie mehr als eine Zeile verwenden, um dasselbe zu tun.


Das ist eigentlich nicht richtig. Dies gibt immer Null zurück, da "su -m $ USER -c <cmd>" immer erfolgreich ist, auch wenn der tatsächliche Befehl darin nicht erfolgreich ist.
Nick

1
@ Nick - Es funktioniert hier. Was ist Ihre Ausgabe? Versuchen Sie es sudo su -m zero2cx -c "/bin/false &> /dev/null"aber mit Ihrem Systembenutzernamen. $?sollte '1' sein.
zero2cx

Ja, mit meinem eigenen Benutzernamen wird erwartungsgemäß "1" zurückgegeben. Aber ich versuche, damit eine App über ihren eigenen Benutzer und nicht über root oder einen anderen Benutzer auszuführen.
Nick

@ Nick - Es sollte mit $ USER=appusernameSet funktionieren , wie Sie es wünschen. Verwenden Sie keinen echten Benutzernamen, sondern verwenden Sie Ihren beabsichtigten Benutzernamen appusername. Es sollte funktionieren, das tut es für mich.
zero2cx
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.