Bash: If / Else в одной строке

204

Я пытаюсь проверить, some_processзапущен ли процесс (предположим, он называется ) на сервере. Если это так, то echo 1, иначе echo 0.

Это команда, которую я использую, но она работает только частично (подробнее см. Ниже). Обратите внимание, что мне нужно написать скрипт в одну строку.

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

Примечание:[s] в some_proces[s]это предотвратить grepот возвращения себя.

Если some_processработает, то "1"получает эхо, что нормально. Однако, если some_processне работает, ничего не отражается.

Артур Римбун
источник
4
Вы можете использовать, ps -Ccmdчтобы найти процессы с именем команды "cmd", которые могут полностью исключить grep. psустановит код выхода на ненулевое значение, если не найдется соответствующий процесс.
Ричи

Ответы:

273

Нет необходимости явно проверять $?. Просто сделать:

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

Обратите внимание, что это зависит от того, что эхо не дает сбоя, что, безусловно, не гарантируется. Более надежный способ написать это:

if ps aux | grep some_proces[s] > /tmp/test.txt; then echo 1; else echo 0; fi
Уильям Перселл
источник
9
Если echo 1не echo 0получится , то будет выполнен. В этом случае echo 1 никогда не завершится ошибкой, но обратите внимание, что A && B || С не если-то-иначе. C может работать, когда A истинно (из проверки оболочки ).
schemacs
@schemacs делает очень правильное замечание: редактирование обеспечивает гораздо лучшую альтернативу.
Уильям Перселл
2
Нужно ли перенаправлять вывод команды ps в файл? Разве это не сработает? if ps aux | grep some_proces[s]; then echo 1; else echo 0; fi, Локально это, кажется, работает для меня. Это потому, что у ОП было перенаправление в команде, которую он пробовал?
1
Нет абсолютно никакой необходимости перенаправлять вывод. Я просто изменяю исходную позицию, так как полагаю, что вывод сохраняется по какой-то причине. Часто такие вещи просто подавляются (с помощью grep -qили перенаправляются на / dev / null).
Уильям Перселл
Я бы использовал pgrep.
pawciobiel
67

&&означает «и в случае успеха»; разместив свое ifзаявление с правой стороны от него, вы гарантируете, что оно будет выполняться только при grepвозврате 0. Чтобы исправить это, используйте ;вместо этого:

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

(или просто используйте разрыв строки).

ruakh
источник
6
+1 Это гораздо лучший ответ, так как он фактически отвечает на вопрос, а не просто предлагает альтернативу.
Уильям Перселл
42

Используйте grep -vcдля игнорирования grepна psвыходе и подсчета строк одновременно.

if [[ $(ps aux | grep process | grep -vc grep)  > 0 ]] ; then echo 1; else echo 0 ; fi
Джон Гилмер
источник
15

Вы можете в полной мере использовать &&и ||оператор , как это:

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

Для исключения самого grep, вы также можете сделать что-то вроде:

ps aux | grep some_proces | grep -vw grep > /tmp/test.txt && echo 1 || echo 0
Кости Сьюдату
источник
2
pgrep -q some_process && echo 1 || echo 0

больше единомышленников здесь

один раз
источник