Подтвердить что ты не робот

Проверьте, выполняется ли процесс Mac с помощью Bash по имени процесса

Как вы проверяете, выполняется ли процесс в Mac OS X с помощью имени процесса в Bash script?

Я пытаюсь написать Bash script, который перезапустит процесс, если он остановился, но ничего не сделает, если он все еще запущен.

4b9b3361

Ответ 1

Разбор этого:

ps aux | grep -v grep | grep -c [-i] $ProcessName

... вероятно, это лучшая ставка для вас.

ps aux перечисляет все запущенные в настоящее время процессы, включая сам скрипт Bash, который анализируется grep -v grep по совету Джейкоба (в комментариях), а grep -c [-i] $ProcessName возвращает необязательное без учета регистра целое число процессов с целочисленным возвратом, предложенным Себастьяном..

Вот короткий скрипт, который делает то, что вам нужно:

#!/bin/bash
PROCESS=myapp
number=$(ps aux | grep -v grep | grep -ci $ProcessName)

if [ $number -gt 0 ]
    then
        echo Running;
fi

ОБНОВЛЕНИЕ: Я изначально включил флаг -i в grep, чтобы сделать его нечувствительным к регистру; Я сделал это, потому что пример программы, которую я пробовал, был python, который в Mac OS X работает как Python - если вы точно знаете пример своего приложения, -i не нужен.

Преимущество этого подхода в том, что он масштабируется вместе с вами - в будущем, если вам нужно убедиться, что, скажем, пять экземпляров вашего приложения запущены, вы уже рассчитываете. Единственное предостережение: если другое приложение имеет имя вашей программы в командной строке, оно может появиться - регулярные выражения в grep решат эту проблему, если вы лукавите (и столкнетесь с этим).

Исследуйте справочные страницы Дарвина по ps, grep и wc.

Ответ 2

Более короткое решение:

if pgrep $PROCESS_NAME; then
    echo 'Running';
fi

Пояснение:

pgrep выходит с 0, если выполняется процесс, соответствующий $PROCESS_NAME, в противном случае он существует с 1.
if проверяет код выхода pgrep, и, поскольку коды выхода идут, 0 успешно.

Ответ 3

Другой способ - использовать (злоупотреблять?) опцию -d команды killall. Параметры -d фактически не уничтожают этот процесс, а вместо этого распечатывают то, что будет сделано. Он также выйдет со статусом 0, если найдет соответствующий процесс, или 1, если он этого не сделает. Объединяя это:

#!/bin/bash
`/usr/bin/killall -d "$1" &> /dev/null`
let "RUNNING = ! $?"     # this simply does a boolean 'not' on the return code
echo $RUNNING

Чтобы отдать должное, я изначально вытащил эту технику из script в установщик iTunes.

Ответ 4

Эта простая команда сделает трюк. Скобки вокруг имени процесса не позволяют команде grep отображаться в списке процессов. Обратите внимание, что после запятой нет пробела. Могут быть некоторые проблемы с переносимостью, поскольку ps в некоторых системах Unix может потребоваться тире перед параметрами:

ps axo pid,command | grep "[S]kype"

Преимущество состоит в том, что вы можете использовать результаты в выражении if следующим образом: '

if [[ ! $(ps axo pid,command | grep "[i]Tunes.app") ]]; then
    open -a iTunes
fi

Или, если вы предпочитаете этот стиль:

[[ ! $(ps axo pid,command | grep "[S]kype") ]] && open -a Skype  || echo "Skype is up"

Еще одно преимущество заключается в том, что вы можете получить pid, добавив канал в awk '{print $1}'.

echo "iTunes pid: $(ps axo pid,command | grep "[i]Tunes.app" | awk '{print $1}')"

Ответ 5

Вы можете использовать killall или kill, в зависимости от того, пытаетесь ли вы найти задачу с помощью PID или по имени.

По имени:

if ! killall -s -0 $PROCESS_NAME >/dev/null 2>&1; then
  # Restart failed app, or do whatever you need to prepare for starting the app.
else
  at -f $0 +30seconds # If you don't have this on cron, you can use /usr/bin/at
fi

По PID:

if ! kill -0 $PID 2>/dev/null; then
  # Restart app, do the needful.
else
  at -f $0 +30seconds
fi

Если вы посмотрите на Руководство по OSX, вы увидите другой набор команд управления процессом; поскольку это не ядро ​​linux, имеет смысл, что они будут управлять процессами по-разному.

https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/killall.1.html

Образец вывода из моего терминала (конечно, вычеркивание пользователя и имени хоста):

[email protected]:~$ kill -0 782 # This was my old, stale SSH Agent.
bash: kill: (782) - No such process
[email protected]:~$ echo $?
1

[email protected]:~$ kill -0 813 # This is my new SSH agent, I only just created.
[email protected]:~$ echo $?
0

Код возврата из kill -0 всегда приведет к безопасному способу проверить, запущен ли процесс, поскольку -0 не посылает сигнал, который когда-либо будет обрабатываться приложением. Он не будет убивать приложение, а "kill" называется "kill", потому что он обычно используется для остановки приложения.

Когда вы смотрите на интерфейсы, которые он использует в источнике, вы увидите, что он фактически взаимодействует с таблицей процессов напрямую (а не grepping потенциально загружаемого вывода из ps) и просто посылает сигнал в приложение. Некоторые сигналы указывают, что приложение должно быть остановлено или остановлено, в то время как другие сигналы говорят ему перезапустить службы или перечитать конфигурацию или повторно открыть файловые дескрипторы для файлов журналов, которые были недавно повернуты. Существует множество вещей, которые могут "убить" и "убить", что не прерывает приложение, и оно регулярно используется для простого отправки сигнала в приложение.

Ответ 6

Мне не хватает репутации, чтобы прокомментировать ответ killall выше, но там killall -s для этого, не отправляя никаких сигналов:

killall -s "$PROCESSNAME" &> /dev/null
if [ $? -eq 0 ]; then
    echo "$PROCESSNAME is running"
    # if you also need the PID:
    PID=`killall -s "$PROCESSNAME" | awk '{print $3}'`
    echo "it PID is $PID"
fi

Ответ 7

Я добавил pidof script, найденный в сети, чтобы использовать регулярные выражения (обычно подстроки) и нечувствителен к регистру

#!/bin/sh
ps axc  |awk "BEGIN{ n=tolower(\"$1\")}\
    tolower(\$5) ~n {print  \$1}";

просто создайте script с именем "pidof" с этим контентом и поместите его в свой путь, т.е. в один из каналов в

echo $PATH

и сделать его исполняемым (возможно, используя sudo)

chmod 755 /usr/local/bin/pidof

и использовать его, как это, конечно

kill -9 `pidof pyth`

Ответ 8

У Mac есть pidof?...

if pidof $processname >/dev/null ; then echo $processname is running ; fi

Ответ 9

Это точно!

pgrep, pkill и pfind для OpenBSD и Darwin (Mac OS X)

http://proctools.sourceforge.net

(также доступно через MacPorts: информация о профилях портов proctools)

pidof by nightproductions.net

Ответ 10

Возможно, слишком поздно для OP, но это может помочь другим пользователям найти этот поток.

Следующая модификация темы amrox выше хорошо работает для перезапуска приложений на моей ОС X:

killall -d TextEdit &> /dev/null && killall TextEdit &> /dev/null; open -a TextEdit

Я использую следующий AppleScript для обновления и перезапуска демонов:

tell application "System Events" to set pwd to POSIX path of container of (path to me)
do shell script "launchctl unload -w /Library/LaunchDaemons/time-test.plist; cp -f " & quoted form of pwd & "/time-test.plist /Library/LaunchDaemons; launchctl load -w /Library/LaunchDaemons/time-test.plist" with administrator privileges

Предполагается, что исходный или обновленный файл plist находится в том же каталоге, что и AppleScript.