Преобразование PID Cygwin в PID Windows
у меня есть процесс, который я отродясь с Cygwin shell-скрипт, и я не могу убить его с помощью , Я получаю это сообщение:
kill: couldn't open pid 1234
Я хотел бы попытаться убить его с С pskill, но я не могу найти способ, чтобы преобразовать Cygwin PID
до Windows PID
это PsKill
поймет. Как я могу это сделать?
6 ответов
вы пробовали запустить cygwin kill вместо bash builtin? Если это Windows PID, введите:
/bin/kill -f 1234
или если это Cygwin PID, введите:
/bin/kill -9 1234
насколько я знаю, нет API для Cygwin, который вы могли бы вызвать, чтобы перевести Cygwin PID в Windows PID. Тем не менее, вы можете проанализировать вывод ps -W
для преобразования. Или, если вы действительно, действительно не хотите этого делать, тогда взгляните на исходный код Cygwin , и посмотрим, откуда у них пиды. Программу Cygwin исходный код ps здесь.. Вы можете написать небольшую утилиту на C, чтобы взять Cygwin pid и дать вам Windows pid.
ps -W
покажет PID Windows в дополнение к PID Cygwin.
или, вы можете сделать это программно, как это:
#include <sys/cygwin.h>
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);
на файловая система proc имеет Windows PID для cygwin pid $pid в /proc/$pid/winpid
.
> notepad&
[1] 11716
> taskkill /f /pid $(</proc/$!/winpid)
ERFOLGREICH: Der Prozess mit PID 11976 wurde beendet.
[1]+ Exit 1 notepad
это работает в оболочке sh:
./${Z_BIN} &
Z_PID=$!
Z_PIDW=`ps -p ${Z_PID} | awk -e '/^[[:space:]]+[[:digit:]+]/{print }'`
Z_BIN содержит вашу программу для выполнения. Z_PID будет содержать cygwin pid и Z_PIDW будет содержать Windows pid для той же программы. Вы можете сохранить Z_PIDW в PID-файл и использовать его позже для убийства или любой другой цели.
Я искал в интернете, чтобы узнать, есть ли у кого-нибудь функция или скрипт для преобразования Cygwin PIDs в Microsoft PIDs. Я ничего не нашел и сделал свой собственный. Я помещаю его здесь для безопасного хранения (когда у меня нет доступа к моему жизненному времени сценариев, которые я запрограммировал). Это становится частым решением для меня в дикой природе.
#!/usr/bin/env bash
# Convert a cygwin PID to a Microsoft PID using bash and perl
ps -W | perl -e '
my ($line, $arg,$errno,@columns);
$errno=1;
while($line = ){
chomp($line);
$line=~s/^\s+//g;s/\s+$//g;
for $arg (@ARGV){
if ($line=~/^${arg}/){
$errno=0;
@columns=split(/\s+/,$line);
print STDOUT $columns[3];
last;
}
}
}
exit($errno);
' "${@}"
The kill using `taskkill` and/or `kill` cygwin terminal.
<pre><code>
taskkill /F /IM ${m1crosoft_pid_goes_here}
kill -9 ${cygwin_pid_goes_here_tmp}
используйте файловый дескриптор, когда вы можете и использовать вместо этого канала.
лучший способ убить запущенные сценарии Bash от Cygwin-использовать SysinternalsPsKill64.exe
. Причина в том, что по Cygwin ps
также дайте PID, которые отличаются от WINPID
.
кроме того, pskill
также -t
флаг, который убивает все дерево процессов, что означает любые другие потоки / подпроцессы, которые мог запустить ваш скрипт. Конечно!--7--> также работает, но он не убивает потомки уже начали скрипт.
# cat sleeper.sh
ZID=$$
WINPID=$(cat /proc/${ZID}/winpid)
echo "WINPID: ${WINPID}"
sleep 10
теперь бегите с:
$ ./sleeper.sh &
[1] 8132
WINPID: 8132
$ ps
PID PPID PGID WINPID TTY UID STIME COMMAND
#5280 1 5280 5280 ? 1001 14:21:40 /usr/bin/mintty
#7496 5684 7496 3836 pty0 1001 20:48:12 /usr/bin/ps
#5684 5280 5684 6052 pty0 1001 14:21:40 /usr/bin/bash
5948 8132 8132 3900 pty0 1001 20:48:11 /usr/bin/sleep
8132 5684 8132 8132 pty0 1001 20:48:11 /usr/bin/bash
как вы видите, это запускает два процесса, главной bash
скрипт и спящий поток. Так что если вы kill -1 8132
нить сна будет продолжать работать, но если вы используете pskill64 -t 8132
, вы убьете всех его потомков тоже. Аналогично linux .