Вопрос

У меня есть процесс, который я запускаю с помощью Сигвин сценарий оболочки, и я не могу убить его с помощью kill команда.Даже с Cygwin убить с -f вариант, я получаю это сообщение:

kill: couldn't open pid 1234

Я хотел бы попытаться убить его с помощью PsKill, но я не могу найти способ конвертировать Cygwin PID к Windows PID что PsKill пойму.Как мне это сделать?

Это было полезно?

Решение

Вы пробовали запустить cygwin kill вместо встроенной команды bash?Если это PID Windows, введите:

/bin/kill -f 1234

или, если это PID Cygwin, введите:

/bin/kill -9 1234

Насколько я знаю, для Cygwin не существует API, который можно было бы вызвать для перевода PID Cygwin в PID Windows.Однако вы можете проанализировать вывод ps -W чтобы сделать преобразование.Или, если вы действительно не хотите этого делать, взгляните на исходный код Cygwin. ps команду и посмотрим, откуда они берут пиды.Сигвин ps исходный код здесь..Вы можете написать небольшую утилиту на C, которая возьмет pid Cygwin и выдаст вам pid Windows.

Другие советы

ps -W отобразит PID Windows в дополнение к PID Cygwin.

Или вы можете сделать это программно следующим образом:

#include <sys/cygwin.h>
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);

А файловая система proc имеет PID Windows для 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 $4}'`

Z_BIN содержит вашу программу для выполнения.Z_PID будет содержать идентификатор cygwin, а Z_PIDW будет содержать идентификатор Windows для той же программы.Вы можете сохранить Z_PIDW в файле pid и использовать его позже для уничтожения или любых других целей.

Я поискал в Интернете, есть ли у кого-нибудь функция или сценарий для преобразования PID Cygwin в PID Microsoft.Я ничего не нашел;поэтому я сделал свой собственный.Я размещаю его здесь для безопасного хранения (когда у меня нет доступа к сценариям, которые я запрограммировал за всю свою жизнь).Это становится частым решением для меня в дикой природе.



    #!/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 — использовать команду Сисинтерналы инструмент PsKill64.exe.Причина в том, что Cygwin ps также укажите PID, которые отличаются от WINPID.

Кроме того, pskill также имеет -t флаг, который уничтожает все дерево процессов, что означает любые другие потоки/подпроцессы, которые мог запустить ваш скрипт.Конечно kill -9 <PID> также работает, но не убивает потомков, уже запущенных сценарием.

# 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 killall команда.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top