Accéder à un code de sortie en dehors d'un su -m $ USER -c "<cmd>"


8

La commande ci-dessous imprime correctement "0" ou "1" en fonction de l'échec ou non car j'ai mis $? à l'intérieur de la commande "su".

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

Cependant, si je fais cela:

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

il affichera toujours "0" car le "su" réel réussira toujours, même si la partie commande échoue.

Une idée comment je peux récupérer le code de sortie du sous-shell?

Réponses:


7

Je viens de corriger presque exactement la même situation. J'espère que cela vous aidera encore, sinon alors peut-être d'autres. Je suis parti de su, pas de sudo, mais comme sudo est destiné à encapsuler une seule autre commande, il devrait vraiment relayer le code de sortie de su. Sinon, vous pouvez également appliquer le correctif ci-dessous au niveau sudo.

Comme vous l'avez noté, le problème principal est que su exécute avec succès sa commande. L'action par défaut consiste alors à signaler qu'elle s'est terminée sans aucun problème et à renvoyer le code de sortie 0. Elle ne "sait" pas qu'un code de sortie non 0 d'une commande était inattendu ou qu'il devrait faire quelque chose avec. Ainsi, la solution est tout simplement de faire revenir su le code de sortie de sa dernière commande. Ça l'a fait pour moi

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

Dans le cas où sudo ne joue pas bien, la commande entière devrait ressembler à ceci (je vérifierais cela pour vous mais je n'ai pas sudo installé)

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

Surveillez l'imbrication des guillemets et assurez-vous que $? n'est pas développé, donc pas de guillemets doubles.


2

Faites écho à la valeur de retour à l'intérieur de la commande et accédez-y à l'extérieur en affectant la commande entière à une variable (à l'aide d'un sous-shell.)

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

0

Vous pouvez toujours utiliser un fichier tmp:

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

Oui, c'est ce que je fais en ce moment, mais j'espérais ne pas compter sur un fichier tmp.
Nick

0

Cela fonctionne dans les shells Zsh / Bash / Bourne:

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

Je ne sais pas pourquoi le code retour n'est pas disponible lorsque vous le demandez dans une seule ligne, mais il est disponible lorsque vous utilisez plusieurs lignes pour faire la même chose.


Ce n'est en fait pas correct. Cela retournera toujours zéro parce que "su -m $ USER -c <cmd>" réussira toujours même si la commande réelle qu'il contient ne réussit pas.
Nick

1
@Nick - Cela fonctionne ici. Quelle est votre sortie? Essayez sudo su -m zero2cx -c "/bin/false &> /dev/null"mais avec votre nom d'utilisateur système. $?devrait être «1».
zero2cx

Ouaip, avec mon propre nom d'utilisateur, il renvoie "1" comme prévu. Mais j'essaie de l'utiliser pour exécuter une application via son propre utilisateur et non root ou tout autre utilisateur.
Nick

@Nick - Cela devrait fonctionner avec $ USER=appusernameset comme vous le souhaitez. N'utilisez pas un vrai nom d'utilisateur, n'utilisez pas votre intention appusername. Ça devrait marcher, ça marche pour moi.
zero2cx
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.