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?

usuario
fonte

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.

Capitão Coder
fonte
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
Aaron Copley
fonte
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
Terdon
fonte
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.

zero2cx
fonte
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