O comando PHP exec tem o resultado 0, mesmo que ocorra um erro

1

Eu tenho este código PHP:

$execout=exec('ssh [email protected] "sudo /etc/init.d/smokeping reload"',$output1,$result);
if($result !=0){
    echo"that can't reload";
}
else{
    echo "successfully reloaded";
}

neste código, sempre fornece o $result = 0 . Por que é que? Às vezes, se o smokeping tem um erro, ele mostra esse erro quando o comando abaixo digitado na linha de comando,

ssh [email protected] "sudo /etc/init.d/smokeping reload"

então isso dá erro de mensagem.

* Reloading latency logger daemon configuration...
ERROR: can't open /etc/smokeping/devices/errorfilename: No such file or   directory
 ...done.

, por isso, tem um erro, mas $result sempre dá o mesmo que 0. (Se houve ou não um erro)

Por que o comando exec se comporta assim (em php e CLI)?

    
por Thusitha Sumanadasa 27.06.2013 / 12:29

2 respostas

0

Encontrei uma pequena resposta para isso. Para o código acima, coloquei 2>&1 no final. Como

$execout=exec('ssh [email protected] "sudo /etc/init.d/smokeping reload 2>&1"',$output1,$result);

Quando ocorre um erro no aplicativo que eu vou recarregar (smokeping), print_r($output); fornece o erro como

Array ( [0] => * Reloading latency logger daemon configuration... [1] => ERROR: can't open /etc/smokeping/devices/errorfilename: No such file or directory [2] => ...done. )

Agora eu posso lidar com isso daqui. Obrigado a todos.

    
por 28.06.2013 / 11:11
2

Em

ssh [email protected] "sudo /etc/init.d/smokeping reload"

Seu escudo

(1) (ou, no seu exemplo, o shell iniciado pelo exec() do PHP) irá analisar essa linha de comando e, se for encontrado, executar um ssh

(2) Comando que contatará um sshd

(3) Servidor no xxx.xxx.xxx.xx que, após autenticação bem-sucedida, chamará shell

(4) Que interpretará essa linha de comando sudo e executará o sudo

(5) Comando que depois de verificar as permissões será executado /etc/init.d/smokeping

(6) Que provavelmente é um script de shell que executa vários comandos.

Várias coisas podem falhar lá. Se todas as etapas de 1 a 5 forem bem-sucedidas, o status de saída de /etc/init.d/smokeping será relatado para o seu shell porque sudo reporta o status de saída do comando executado e o shell remoto sai com o status de saída do último comando executado e ssh informa o status de saída do shell remoto.

Agora, os comandos retornam um status de saída diferente de zero, por convenção, para informar ao chamador que eles não conseguiram fazer o que foi solicitado a fazer.

No seu caso, /etc/init.d/smokeping decidiu que qualquer erro que ocorreu não foi suficiente para garantir um status de saída diferente de zero, ou que o script não está escrito corretamente e não retorna com um status de saída diferente de zero após uma falha (ou algum caso patológico envolvendo mau comportamento ou configuração incorreta de ssh , sudo ou o shell remoto).

Os scripts

/etc/init.d geralmente são escritos com set -e . Com esse sinalizador ativado, o shell interpretando o script por padrão sairá quando um comando executado falhar (com o status de saída diferente de zero do comando com falha), o que me faz pensar que podemos estar na primeira situação: "smokeping" decide informar que foi recarregado com sucesso.

Um exemplo de um caso patológico poderia ser, por exemplo: bash usado como o shell remoto ( bash lê o ~/.bashrc quando invocado sobre ssh mesmo que não sejam shells interativos), e o ~/.bashrc tem algo como:

trap 'whatever...; exit 0' EXIT

O que faria com que o status de saída de shells interativos ou shells iniciados acima de ssh ou rsh sempre fosse 0 .

    
por 27.06.2013 / 13:44

Tags