Bash: instruction If / Else sur une seule ligne

204

J'essaie de vérifier si un processus (supposons qu'il s'appelle some_process) s'exécute sur un serveur. Si c'est le cas, alors écho 1, sinon écho 0.

C'est la commande que j'utilise mais elle ne fonctionne que partiellement (plus d'informations ci-dessous). Notez que je dois écrire le script sur une seule ligne.

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

Note: Le [s]en some_proces[s]est d'empêcher grepde se retourner.

Si some_processest en cours d'exécution, alors "1"fait écho, ce qui est bien. Cependant, s'il some_processn'est pas en cours d'exécution, rien ne se répercute.

Arthur Rimbun
la source
4
Vous pouvez utiliser ps -Ccmdpour rechercher des processus dont le nom de commande est "cmd", ce qui peut éliminer complètement le grep. psdéfinira le code de sortie sur une valeur non nulle s'il ne trouve pas de processus correspondant.
rici

Réponses:

273

Il n'est pas nécessaire de vérifier explicitement $?. Faites juste:

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

Notez que cela repose sur l'écho qui n'échoue pas, ce qui n'est certainement pas garanti. Un moyen plus fiable d'écrire ceci est:

if ps aux | grep some_proces[s] > /tmp/test.txt; then echo 1; else echo 0; fi
William Pursell
la source
9
En cas d' echo 1échec, alors echo 0sera exécuté. Dans ce cas, l'écho 1 n'échouera jamais, mais notez que A && B || C n'est pas si-alors-sinon. C peut s'exécuter lorsque A est vrai. (À partir de shellcheck ).
schemacs
@schemacs fait un point très valable: l'édition pour fournir une bien meilleure alternative.
William Pursell
2
Est-il nécessaire de rediriger la sortie de la commande ps vers un fichier? Cela ne fonctionnerait-il pas? if ps aux | grep some_proces[s]; then echo 1; else echo 0; fi. Localement, cela semble fonctionner pour moi. Est-ce parce que OP avait la redirection dans la commande qu'il a essayée?
1
Il n'est absolument pas nécessaire de rediriger la sortie. Je singe simplement la position d'origine, car je suppose que la sortie est enregistrée pour une raison. Souvent, ce genre de chose est simplement supprimé (avec grep -qou redirigé vers / dev / null).
William Pursell
J'utiliserais pgrep.
pawciobiel
67

&&signifie "et en cas de succès"; en plaçant votre ifrelevé à droite de celui-ci, vous vous assurez qu'il ne s'exécutera qu'en cas de grepretour 0. Pour le réparer, utilisez ;plutôt:

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

(ou utilisez simplement un saut de ligne).

ruakh
la source
6
+1 C'est une bien meilleure réponse, car elle répond en fait à la question plutôt que de simplement fournir une alternative.
William Pursell
42

Utilisez grep -vcpour ignorer grepla pssortie et compter les lignes simultanément.

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

Vous pouvez utiliser pleinement les opérateurs &&et ||comme ceci:

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

Pour exclure grep lui-même, vous pouvez également faire quelque chose comme:

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

plus d'oneliners ici

une fois que
la source