Pergunta

Eu tenho um processo que desonesto com um Cygwin script de shell, e não consigo matá -lo com o kill comando. Mesmo com o Cygwin Kill com o -f opção, recebo esta mensagem:

kill: couldn't open pid 1234

Eu gostaria de tentar matá -lo com Pskill, mas não consigo encontrar uma maneira de converter o Cygwin PID para um Windows PID este PsKill vai entender. Como eu posso fazer isso?

Foi útil?

Solução

Você já tentou executar a matança de Cygwin em vez da festa embutida? Se for um PID do Windows, digite:

/bin/kill -f 1234

ou se for um cygwin pid, digite:

/bin/kill -9 1234

Até onde eu sei, não há API para o Cygwin que você poderia ligar para traduzir um PID de Cygwin em um PID do Windows. No entanto, você pode analisar a saída de ps -W Para fazer a conversão. Ou, se você realmente, realmente não quer fazer isso, dê uma olhada no código -fonte do Cygwin ps comando e veja de onde eles tiram os PIDs. O cygwin O código -fonte do PS está aqui.. Você pode escrever um pequeno utilitário em C para pegar o PID do Cygwin e fornecer um PID do Windows.

Outras dicas

ps -W mostrará o PID do Windows, além do Cygwin PID.

Ou, você pode fazer isso programaticamente assim:

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

o Sistema de arquivos proc tem o pid Windows para cygwin pid $ pid em /proc/$pid/winpid.

> notepad&
[1] 11716
> taskkill /f /pid $(</proc/$!/winpid)
ERFOLGREICH: Der Prozess mit PID 11976 wurde beendet.
[1]+  Exit 1                  notepad

Isso funciona em sh shell:

./${Z_BIN} &
Z_PID=$!
Z_PIDW=`ps -p ${Z_PID} | awk -e '/^[[:space:]]+[[:digit:]+]/{print $4}'`

Z_BIN contém seu programa para executar. O Z_PID conterá o Cygwin PID e o Z_PIDW conterá o Windows PID para o mesmo programa. Você pode salvar o Z_PIDW em um arquivo PID e usá -lo posteriormente para matar ou qualquer outro propósito.

Eu procurei na web para ver se alguém tinha uma função ou script para converter PIDs de cygwin em PIDs da Microsoft. Eu não encontrei nenhum; Então eu fiz o meu próprio. Estou colocando isso aqui para manutenção segura (quando não tenho acesso à minha vida em scripts que programei). Isso está se tornando uma solução frequente para mim na natureza.



    #!/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}

Use o descritor de arquivo quando puder e usar em vez desse tubo.

A melhor maneira de matar scripts bash em execução de Cygwin é usar o Sysinternals ferramenta PsKill64.exe. A razão é que o cygwin ps Dê também PIDs que são diferentes de WINPID.

Além disso, pskill também tem o -t Bandeira que mata toda a árvore do processo, o que significa quaisquer outros threads/subprocessos que seu script possa ter iniciado. É claro kill -9 <PID> Também funciona, mas não mata descendentes já iniciados pelo roteiro.

# cat sleeper.sh
ZID=$$
WINPID=$(cat /proc/${ZID}/winpid)
echo "WINPID: ${WINPID}"
sleep 10

Agora corra com:

$ ./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

Como você vê, isso inicia dois processos, o principal bash Script e o fio do sono. Então, se você kill -1 8132 O tópico do sono continuará correndo, mas se você usar pskill64 -t 8132, você matará todos os seus descendentes também. Análogo ao Linux killall comando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top