Как проверить, существует ли идентификатор процесса (PID)
в bash-скрипт, я хочу сделать следующее (в псевдо-код):
if [ a process exists with $PID ]; then
kill $PID
fi
что соответствующее выражение для условного оператора?
9 ответов
чтобы проверить наличие процесса, используйте
kill -0 $pid
но так же, как @unwind сказал, Если вы собираетесь убить его в любом случае, просто
kill $pid
или у вас будет состояние гонки.
если вы хотите игнорировать вывод текста kill
и сделать что-то на основе кода выхода, вы можете
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
лучший способ-это:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
проблема:
kill -0 $PID
код выхода будет ненулевым, даже если pid запущен, и у вас нет разрешения убить его. Например:
kill -0 1
и
kill -0 $non-running-pid
имеют неразличимый (ненулевой) код выхода для обычного пользователя, но процесс инициализации (PID 1), безусловно, работает.
обсуждение
ответы, обсуждающие условия убийства и гонки, точно правильно, если тело теста является "убить". Я пришел за генералом.--17-->как вы проверяете существование PID в bash".
метод /proc интересен, но в некотором смысле нарушает дух абстракции команды "ps", т. е. вам не нужно искать в /proc, потому что что, если Линус решит назвать файл "exe" чем-то другим?
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
или
if [ -n "$(ps -p $PID -o pid=)" ]
в последней форме, -o pid=
- выходной формат для отображения только столбца идентификатора процесса без заголовка. Кавычки необходимые для непустого строкового оператора -n
дать действительный результат.
у вас есть два пути:
давайте начнем с поиска конкретного приложения в моем ноутбуке:
[root@pinky:~]# ps fax | grep mozilla
3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2 S+ 0:00 \_ grep mozilla
все примеры теперь будут искать PID 3358.
Первый способ: запустите "ps aux" и grep для PID во втором столбце. В этом примере я ищу firefox, а затем для него PID:
[root@pinky:~]# ps aux | awk '{print }' | grep 3358
3358
таким образом, ваш код будет:
if [ ps aux | awk '{print }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Второй способ: просто ищите что-то в
Я думаю, что это плохое решение, которое открывается для условий гонки. Что делать, если процесс умирает между вашим тестом и вашим призывом убить? Тогда убить не удастся. Так почему бы просто не попробовать убить во всех случаях, и проверить возвращаемое значение, чтобы узнать, как все прошло?
похоже, вы хотите
wait $PID
что вернется, когда $pid
заканчивается.
в противном случае вы можете использовать
ps -p $PID
чтобы проверить, если процесс все еще жив (это более эффективно, чем kill -0 $pid
потому что он будет работать, даже если у вас нет pid).
здесь я храню PID в файл .pid (что похоже на /run/...) и только выполнить сценарий, если он еще не выполняется.
#!/bin/bash
if [ -f .pid ]; then
read pid < .pid
echo $pid
ps -p $pid > /dev/null
r=$?
if [ $r -eq 0 ]; then
echo "$pid is currently running, not executing twice, exiting now..."
exit 1
fi
fi
echo $$ > .pid
# do things here
rm .pid
Примечание: состязания как не проверить, как это называется пид. если система перезагружена и .pid существует, но используется другим приложением, что может привести к "непредвиденным последствиям".
например в GNU/Linux вы можете использовать:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
или что-то вроде
Pin=$(ps -A | grep name | awk 'print }')
echo $PIN
и это показывает вам имя приложения, только имя без идентификатора.