2009-11-05 14 views
7

Tengo un proceso que genero con un script de shell Cygwin, y no puedo eliminarlo con el comando kill. Incluso con el Cygwin kill con la opción -f, me sale este mensaje:Convierta un PID de Cygwin en un PID de Windows

kill: couldn't open pid 1234 

me gustaría tratar de matarlo con PsKill, pero no puedo encontrar una manera de convertir el Cygwin PID a un Windows PID que PsKill entenderán. ¿Cómo puedo hacer eso?

Respuesta

10

¿Has probado ejecutar cygwin kill en lugar del bash incorporado? Si se trata de un PID de Windows a continuación, escriba:

/bin/kill -f 1234 

o si se trata de un PID Cygwin a continuación, escriba:

/bin/kill -9 1234 

Por lo que yo sé no hay ninguna API para Cygwin que se podría llamar para traducir un PID de Cygwin a un PID de Windows. Sin embargo, puede analizar el resultado de ps -W para realizar la conversión. O bien, si realmente no quiere hacer eso, eche un vistazo al código fuente del comando Cygwin ps y vea de dónde obtienen las pids. El Cygwin ps source code is here.. Puede escribir una pequeña utilidad en C para tomar el pid Cygwin y darle un pid de Windows.

+0

Sí, es la muerte de Cygwin que estoy usando. Intenté/bin/kill -f -9 1234 y/bin/kill -9 1234 sin éxito. 1234 es un PID de Cygwin. – Jazz

+2

Si usa -f, debe darle el Windows PID de ps -W –

+1

Además de esta gran respuesta, a veces, cuando el proceso está bloqueado desde dentro de Windows, Cygwin kill genera el mensaje "could not open pid 1234". El proceso necesita ser desbloqueado desde adentro de Windows primero. – Secko

6

ps -W mostrará el PID de Windows además del Cygwin PID.

O bien, puede hacerlo mediante programación como esto:

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

Sí, lo sé, pero esperaba una forma directa de hacerlo en lugar de analizar la salida ps. – Jazz

+0

Alternativa programática agregada –

1

Esto funciona en sh:

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

Z_BIN contiene el programa a ejecutar. Z_PID contendrá cygwin pid y Z_PIDW contendrá Windows pid para el mismo programa. Puede guardar Z_PIDW en un archivo pid y usarlo más tarde para matar o para cualquier otro propósito.

0

Busqué en la web para ver si alguien tenía una función o script para convertir los PID de cygwin en PID de Microsoft. No encontré ninguno; así que hice mi propio. Lo estoy poniendo aquí para su custodia (cuando no tengo acceso a mi tiempo de vida de scripts que he programado). Esto se está convirtiendo en una solución frecuente para mí en la naturaleza.



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

Uso descriptor de archivo y cuando se puede utilizar en lugar de que la tubería.

+0

La gramática y el texto de copiar y pegar se malinterpretaron en la parte inferior. Pero mi jujitsu stackexhange.com no es genial. Estoy fuera. – MyMightyJoeYoung

2

El proc file system tiene el PID de Windows para cygwin PID $ pid en /proc/$pid/winpid.

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

¡Esta es de hecho la manera correcta de hacerlo! – not2qubit

0

La mejor manera de matar a la ejecución de scripts Bash de Cygwin está utilizando la herramienta PsKill64.exeSysinternals. El motivo es que Cygwin's ps también proporciona PID que son diferentes de WINPID.

Además, pskill también tiene el indicador -t que mata todo el árbol de procesos, lo que significa cualquier otro subprocesos/subprocesos que su secuencia de comandos pueda haber iniciado. Por supuesto, kill -9 <PID> también funciona, pero no mata descendientes ya iniciados por el script.

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

Ahora ejecute con:

$ ./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 se ve, este comienza dos procesos, el principal bash guión y el hilo del sueño. Entonces, si kill -1 8132 el hilo de suspensión continuará ejecutándose, pero si usa pskill64 -t 8132, también matará a todos sus descendientes. De forma análoga al comando linux killall.