Bash: Instrukcja If / Else w jednym wierszu

204

Usiłuję sprawdzić, czy proces (zakładając, że się nazywa some_process) jest uruchomiony na serwerze. Jeśli tak, to echo 1, w przeciwnym razie echo 0.

To polecenie, którego używam, ale działa tylko częściowo (więcej informacji poniżej). Zauważ, że muszę napisać skrypt w jednym wierszu.

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

Uwaga:[s] w some_proces[s]to, aby zapobiec greppowrotowi się.

Jeśli some_processjest uruchomiony, wyświetla "1"się echo, co jest w porządku. Jeśli jednak some_processnie działa, nic się nie odbija.

Arthur Rimbun
źródło
4
Możesz użyć ps -Ccmddo znalezienia procesów, których nazwa polecenia to „cmd”, co może całkowicie wyeliminować grep. psustawi kod wyjścia na pewną niezerową wartość, jeśli nie uda się znaleźć pasującego procesu.
rici

Odpowiedzi:

273

Nie ma potrzeby jawnego sprawdzania $?. Po prostu zrób:

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

Zauważ, że polega to na tym, że echo nie zawodzi, co z pewnością nie jest gwarantowane. Bardziej niezawodnym sposobem na napisanie tego jest:

if ps aux | grep some_proces[s] > /tmp/test.txt; then echo 1; else echo 0; fi
William Pursell
źródło
9
Jeśli się echo 1nie powiedzie, echo 0zostanie wykonany. W takim przypadku echo 1 nigdy nie zawiedzie, ale zwróć uwagę, że A i B || C nie jest, jeśli-to-jeszcze. C może działać, gdy A jest prawdziwe. (Z kontroli powłoki ).
schemacs
@schemacs ma bardzo ważny punkt: edycja w celu zapewnienia znacznie lepszej alternatywy.
William Pursell
2
Czy konieczne jest przekierowanie wyjścia polecenia ps do pliku? Czy to nie zadziała? if ps aux | grep some_proces[s]; then echo 1; else echo 0; fi. Lokalnie wydaje mi się, że działa. Czy to dlatego, że OP miał przekierowanie w poleceniu, którego próbował?
1
Nie ma absolutnie potrzeby przekierowywania wyjścia. Po prostu małpuję pierwotną pozycję, ponieważ zakładam, że wyjście zostało zapisane z jakiegoś powodu. Często tego rodzaju rzeczy są po prostu tłumione (z grep -qlub przekierowane do / dev / null).
William Pursell
Chciałbym użyć pgrep.
pawciobiel
67

&&oznacza „a jeśli się powiedzie”; umieszczając swoje ifoświadczenie po prawej stronie, upewniasz się, że będzie działać tylko w przypadku grepzwrotów 0. Aby to naprawić, użyj ;zamiast tego:

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

(lub po prostu użyj podziału linii).

ruakh
źródło
6
+1 To jest znacznie lepsza odpowiedź, ponieważ faktycznie odpowiada na pytanie, a nie tylko stanowi alternatywę.
William Pursell
41

Użyj, grep -vcaby zignorować grepdane pswyjściowe i policzyć linie jednocześnie.

if [[ $(ps aux | grep process | grep -vc grep)  > 0 ]] ; then echo 1; else echo 0 ; fi
John Gilmer
źródło
15

Możesz w pełni korzystać z następujących operatorów &&i ||:

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

Aby wykluczyć sam grep, możesz również zrobić coś takiego:

ps aux | grep some_proces | grep -vw grep > /tmp/test.txt && echo 1 || echo 0
Costi Ciudatu
źródło
2
pgrep -q some_process && echo 1 || echo 0

więcej onelinerów tutaj

pewnego razu
źródło