Acessando um código de saída fora de um su -m $ USER -c “<cmd>”


8

O comando abaixo imprime "0" ou "1" corretamente, dependendo da falha ou não, porque coloquei $? dentro do comando "su".

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

No entanto, se eu fizer isso:

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

sempre imprimirá "0" porque o "su" real sempre será bem-sucedido, mesmo se a parte do comando falhar.

Alguma idéia de como posso recuperar o código de saída do subshell?

Respostas:


7

Eu apenas consertei quase exatamente a mesma situação. Espero que ainda ajude você, se não for o caso, talvez outros. Comecei pelo su, não pelo sudo, mas como o sudo pretende envolver um único outro comando, ele realmente deve retransmitir o código de saída do su. Caso contrário, você também pode aplicar a correção abaixo no nível do sudo.

Como você notou, o principal problema é que o comando executa com êxito. A ação padrão é relatar que foi concluída sem problemas e retornar o código de saída 0. Ele não "sabe" que um código de saída diferente de 0 de um comando foi inesperado ou que deve fazer algo com ele. Portanto, a solução é simplesmente fazer su retornar o código de saída do seu último comando. Isso fez por mim

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

Caso o sudo não tenha um bom desempenho, todo o comando deve ser algo assim (eu verificaria isso para você, mas não tenho o sudo instalado)

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

Preste atenção ao aninhamento de aspas e certifique-se de $? não é expandido, portanto, não há aspas duplas.


2

Efetue eco do valor de retorno dentro do comando e acesse-o fora, atribuindo o comando inteiro a uma variável (usando um subshell.)

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

0

Você sempre pode usar um arquivo tmp:

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

Sim, é isso que estou fazendo agora, mas esperava não depender de um arquivo tmp.
Nick

0

Isso funciona nos shells Zsh / Bash / Bourne:

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

Não sei por que o código de retorno não está disponível quando você solicita em uma linha, mas está disponível quando você usa mais de uma linha para fazer a mesma coisa.


Na verdade, isso não está correto. Isso sempre retornará zero, pois o "su -m $ USER -c <cmd>" sempre será bem-sucedido, mesmo que o comando real dentro dele não seja.
Nick

11
@ Nick - Funciona aqui. Qual é a sua saída? Tente, sudo su -m zero2cx -c "/bin/false &> /dev/null"mas com o nome de usuário do seu sistema. $?deve ser '1'.
Zero2cx 21/09/12

Sim, com meu próprio nome de usuário, ele retorna "1" conforme o esperado. Mas estou tentando usar isso para executar um aplicativo por meio de seu próprio usuário e não como root ou qualquer outro usuário.
Nick

@ Nick - Ele deve funcionar com o $ USER=appusernameconjunto que você desejar. Não use um nome de usuário real, use o pretendido appusername. Deveria funcionar, funciona para mim.
Zero2cx 22/09/12
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.