Відповіді:
Щоб перевірити наявність процесу, використовуйте
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
kill
дещо неправильно названий тим, що це не обов'язково вбиває процес. Він просто посилає процес сигнал. kill $PID
еквівалентна тому kill -15 $PID
, що передає сигнал 15, SIGTERM в процес, що є інструкцією припинити. Немає сигналу 0, це особливе значення, яке означає kill
просто перевірити, чи може сигнал надсилатися до процесу, який для більшості цілей більш-менш еквівалентний перевірці, чи існує. Дивіться linux.die.net/man/2/kill та linux.die.net/man/7/signal
kill -0
, я, власне, мушу це зробити: kill -0 25667 ; echo $?
- і тоді, якщо я отримаю 0
повернення, процес із цим PID можна вбити; а якщо PID процесу (скажімо) не існує, то $?
буде 1
, що свідчить про збій. Це правильно?
Найкращий спосіб:
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
мати нерозрізний (ненульовий) код виходу для звичайного користувача, але процес init (PID 1) звичайно працює.
Відповіді, що обговорюють умови вбивства та перегонів, є абсолютно правильними, якщо основна частина тесту є "вбивством". Я прийшов шукати загальне " як ви протестуєте на наявність PID в баші ".
Метод / proc цікавий, але в деякому сенсі порушує дух абстракції команди "ps", тобто вам не потрібно заходити шукати / proc, бо що робити, якщо Лінус вирішить викликати файл "exe" чимось іншим?
-p
непотрібне, принаймні в такому випадку. ps $PID
має точно такий же результат.
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
або
if [ -n "$(ps -p $PID -o pid=)" ]
В останньому вигляді -o pid=
- це вихідний формат для відображення лише стовпця ідентифікатора процесу без заголовка. Цитати необхідні, щоб оператор не порожнього рядка -n
дав дійсний результат.
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
варіанти та функції, як правило, відрізняються між платформами, тому це все ще не повністю портативно.
$PID
порожній, то [ -e /proc/$PID ]
все одно поверне справжнє значення, оскільки /proc/
каталог все ще існує.
У вас є два способи:
Почнемо з пошуку конкретного додатка на своєму ноутбуці:
[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" та натисніть на PID. У цьому прикладі я шукаю firefox, а потім його PID:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
Тож ваш код буде:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Другий спосіб : просто шукайте щось у /proc/$PID
каталозі. У цьому прикладі я використовую "exe", але ви можете використовувати будь-що інше.
[root@pinky:~]# ls -l /proc/3358/exe
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash
Тож ваш код буде:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
До речі: у чому справа kill -9 $PID || true
?
Редагувати:
Після того, як я кілька місяців замислювався над цим .. (близько 24 ...) оригінальна ідея, яку я дав тут, - це приємний хакер, але дуже нерепортативний. Хоча він викладає кілька деталей реалізації Linux, він не працюватиме на Mac, Solaris або * BSD. Він може навіть вийти з ладу на майбутніх ядрах Linux. Будь ласка, використовуйте "ps", як описано в інших відповідях.
/proc/$PID/exe
не є звичайним файлом. Отже, [ -f /proc/$PID/exe ]
завжди поверне false
результат. Спробуйте [ -h /proc/$PID/exe ]
.
Здається, що хочеш
wait $PID
який повернеться після $pid
закінчення.
Інакше можна використовувати
ps -p $PID
щоб перевірити, чи процес все ще живий (це ефективніше, ніж kill -0 $pid
тому, що він буде працювати, навіть якщо у вас немає власного підручника).
pid 123 is not a child of this shell
Я думаю, що це погане рішення, яке відкриває для перегонів умови. Що робити, якщо процес загине між вашим тестом і вашим закликом вбити? Тоді вбити не вдасться. То чому б не просто спробувати вбити в усіх випадках і перевірити його повернене значення, щоб дізнатися, як воно пройшло?
kill -9
. Це просто миттєво вбиває процес, не даючи йому шансу очиститись після себе. Замість цього використовуйте, kill
що еквівалентно kill -15
. Якщо це не працює, слід з’ясувати, чому, і лише в крайньому випадку kill -9
.
тут я зберігаю 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 $0 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 $4}')
echo $PIN
і це показує назву програми, а саме ім'я без ідентифікатора.
pidof
не повертає негативне число, оскільки від'ємний PID не має жодного сенсу, і ви не можете вбити init
, тому ваш умовний сенс не має сенсу (і крім того, вам потрібно буде уникнути, >
щоб запобігти його переадресації). Ви хочете перевірити наявність порожнього результату, але, звичайно, як і будь-який пристойний інструмент, pidof
встановлює код виходу, щоб повідомити, чи спрацювало воно, тож правильне рішення - if Pid=$(pidof 'process_name'); then ...
або (якщо вам не знадобиться значення Pid
згодом), простоif pidof 'process_name'; then...
pidof
приклад насичений непорозуміннями щодо того, як test
працює баш . gnu.org/software/bash/manual/html_node/…
код нижче перевіряє, чи працює мій процес, якщо так нічого не робити.
давайте перевірятимемо нові повідомлення від Amazon SQS щогодини і лише в тому випадку, якщо процес не працює.
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
/usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
echo "do nothing, just smile =)"
fi
exit $?