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.


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

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).


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

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.