Я недавно сталкивался с этим в сценарии оболочки.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
Что делает kill -0 ...
?
kill -0 $pid
сценарий оболочки? а также что делает kill 0 на самом деле? ,
Я недавно сталкивался с этим в сценарии оболочки.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
Что делает kill -0 ...
?
kill -0 $pid
сценарий оболочки? а также что делает kill 0 на самом деле? ,
Ответы:
Это немного трудно подобрать, но если вы посмотрите на следующие 2 справочные страницы, вы увидите следующие заметки:
убить (1)$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
убить (2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed;
this can be used to check for the existence of a process ID or process
group ID.
...
Таким образом, сигнал 0 на самом деле ничего не отправит на PID вашего процесса, но проверит, есть ли у вас разрешения для этого.
Одно очевидное место было бы, если бы вы пытались определить, есть ли у вас разрешения на отправку сигналов запущенному процессу через kill
. Вы можете проверить перед отправкой фактического kill
сигнала, который вы хотите, обернув проверку, чтобы убедиться, что это kill -0 <PID>
было сначала разрешено.
Скажем, процесс запускался пользователем root следующим образом:
$ sudo sleep 2500 &
[1] 15693
Теперь в другом окне, если мы запустим эту команду, мы можем подтвердить, что этот PID работает.
$ pgrep sleep
15693
Теперь давайте попробуем эту команду, чтобы увидеть, есть ли у нас доступ для отправки этих сигналов PID через kill
.
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
Так что это работает, но вывод выдаёт сообщение от kill
команды, что у нас нет прав. Ничего страшного, просто поймайте STDERR и отправьте /dev/null
.
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
Итак, мы могли бы сделать что-то вроде этого killer.bash
:
#!/bin/bash
PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then
echo "you don't have permissions to kill PID:$PID"
exit 1
fi
kill -9 $PID
Теперь, когда я запускаю вышеупомянутое как пользователь без полномочий root:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
Однако, когда он запускается с правами root:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
pgrep
, ps
анализируя или test -e /proc/$PID
в портативных записках, но kill -0
работает везде. Если вы получили PID, который может быть устаревшим - например, /var/run
запись - это переносной способ проверить, все еще ли запущен процесс.
kill -0 $(pgrep sleep)
могут не обязательно означают , что вы как раз слабые , он возвращает ложь , если нет sleep
команды работает, или если есть более чем один и есть один , вы не можете убить, или если один из Снов умирают между pgrep и убийством команды запускаются.
kill -0
(или его более переносимый вариант POSIX kill -s 0
) проходит процесс отправки сигнала, но фактически не отправляет его. Это особенность лежащего в основе C API, которую команда shell предоставляет простым способом.
kill -s 0 -- "$pid"
таким образом, проверяется, существует ли запущенный процесс с заданным PID (или PGID, если $pid
он отрицательный), и будет ли текущий процесс иметь разрешение на отправку (любому из процессов в группе процессов в случае отрицательного $pid
) сигнала. В основном это способ проверить, жив ли процесс (или группа процессов).
Имейте в виду, что даже если есть запущенный процесс с ожидаемыми PID и разрешениями, это не обязательно тот процесс, который вы ожидаете. Возможно, что ожидаемый вами процесс умер раньше, и его PID был повторно использован для несвязанного процесса. Правильный способ контролировать процессы - позволить родителю делать это - PID процесса не используется повторно до тех пор, пока его родитель не подтвердит его смерть (вот почему существуют зомби ), поэтому родительский процесс может надежно идентифицировать своих детей по их PID.
Он kill -0 $pid
сообщает вам, существует ли процесс с $pid
.
Во фрагменте
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
блок ... do something ...
выполняется, если /path/to/file.pid
запущен процесс с сохраненным в нем идентификатором PID, и - если фрагмент не работает от имени пользователя root - если идентификатор PID выполняется под тем же пользователем.
Стандарт POSIX определяет роль 0
сигнала:
Если sig равно 0 (нулевой сигнал), выполняется проверка ошибок, но сигнал фактически не отправляется. Нулевой сигнал может быть использован для проверки правильности pid.
(kill (3p), POSIX.1-2008 - аналогичная формулировка в POSIX.1-2001)
Обратите внимание, что POSIX определяет оба стиля kill -0
и kill -s 0
стиль командной строки (kill (1p)).
В отличие от интерфейса kill syscall, kill
команда не может использоваться для надежной проверки на наличие PID, принадлежащих другим пользователям (как обычным пользователям), например:
$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1
против
$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1
При вызове системного вызова kill можно надежно различить эти случаи, посмотрев на errno
значение (см., Например, пример Python ).
trap
командой Бэша и 0 по сравнению с сигналом 0 изkill
: Что такое сигнал 0 в команде прерывания?