Bash: declaração If / Else em uma linha

204

Estou tentando verificar se um processo (suponha que seja chamado some_process) está sendo executado em um servidor. Se for, então eco 1, caso contrário, eco 0.

Este é o comando que estou usando, mas ele funciona apenas parcialmente (mais informações abaixo). Note que eu preciso escrever o script em uma linha.

ps aux | grep some_proces[s] > /tmp/test.txt && if [ $? -eq 0 ]; then echo 1; else echo 0; fi

Nota: O [s]no some_proces[s]é para evitar grepde retornar em si.

Se some_processestiver em execução, o "1"eco será exibido, o que é bom. No entanto, se some_processnão estiver em execução, nada será repetido.

Arthur Rimbun
fonte
4
Você pode usar ps -Ccmdpara encontrar processos cujo nome de comando seja "cmd", que pode eliminar completamente o grep. psdefinirá o código de saída para um valor diferente de zero se ele não encontrar um processo de correspondência.
rici

Respostas:

273

Não há necessidade de verificar explicitamente $?. Apenas faça:

ps aux | grep some_proces[s] > /tmp/test.txt && echo 1 || echo 0 

Observe que isso depende do eco não falhar, o que certamente não é garantido. Uma maneira mais confiável de escrever isso é:

if ps aux | grep some_proces[s] > /tmp/test.txt; then echo 1; else echo 0; fi
William Pursell
fonte
9
Se echo 1falhar, echo 0será executado. Nesse caso, o eco 1 nunca falhará, mas observe que A&& B || C não é se-então-outro. C pode ser executado quando A for verdadeiro. (Da verificação de shell ).
schemacs
O @schemacs faz uma observação muito válida: editar para fornecer uma alternativa muito melhor.
William Pursell
2
É necessário redirecionar a saída do comando ps para um arquivo? Isso não funcionaria? if ps aux | grep some_proces[s]; then echo 1; else echo 0; fi. Localmente, parece funcionar para mim. É porque o OP teve o redirecionamento no comando que ele tentou?
1
Não há absolutamente nenhuma necessidade de redirecionar a saída. Eu apenas imito a posição original, pois presumo que a saída está sendo salva por um motivo. Freqüentemente esse tipo de coisa é apenas suprimido (com grep -qou redirecionado para / dev / null).
William Pursell
Eu usaria pgrep.
pawciobiel
67

&&significa "e se for bem-sucedido"; colocando sua ifdeclaração no lado direito, você garante que ela só será executada se grepretornar 0. Para corrigi-lo, use ;:

ps aux | grep some_proces[s] > /tmp/test.txt ; if [ $? -eq 0 ]; then echo 1; else echo 0; fi

(ou apenas use uma quebra de linha).

ruakh
fonte
6
+1 Esta é uma resposta muito melhor, pois na verdade responde à pergunta, em vez de apenas fornecer uma alternativa.
William Pursell
41

Use grep -vcpara ignorar grepna pssaída e conte as linhas simultaneamente.

if [[ $(ps aux | grep process | grep -vc grep)  > 0 ]] ; then echo 1; else echo 0 ; fi
John Gilmer
fonte
15

Você pode fazer pleno uso dos operadores &&e ||assim:

ps aux | grep some_proces[s] > /tmp/test.txt && echo 1 || echo 0

Para excluir o próprio grep, você também pode fazer algo como:

ps aux | grep some_proces | grep -vw grep > /tmp/test.txt && echo 1 || echo 0
Costi Ciudatu
fonte
2
pgrep -q some_process && echo 1 || echo 0

mais oneliners aqui

uma vez
fonte