Pregunta

Tengo un proceso que aparecen con un script de shell Cygwin , y no soy capaz de matarlo con el comando kill. Incluso con el Cygwin matar con la opción -f, me sale este mensaje:

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 va a entender. ¿Cómo puedo hacer eso?

¿Fue útil?

Solución

¿Ha tratado de ejecutar el cygwin matar en lugar de la orden interna fiesta? Si se trata de un PID de Windows a continuación, escriba:

/bin/kill -f 1234

o si es un Cygwin PID 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 Cygwin PID para un PID de Windows. Sin embargo, se podría analizar la salida de ps -W para hacer la conversión. O, si realmente, realmente no quiere hacer eso, a continuación, echar un vistazo al código fuente para el comando ps Cygwin, y ver de dónde sacan los PIDs de. El Cygwin ps código fuente está aquí. . Se podría escribir una pequeña utilidad en C para tomar el Cygwin pid y darle un PID de Windows.

Otros consejos

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

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

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

Esto funciona en shell sh:

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

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

He buscado en la web para ver si alguien tenía una función o un script para convertir los PID cygwin a Microsoft PID. He encontrado ninguno; así que hice mi propia. Lo estoy poniendo aquí para su custodia (cuando no tengo acceso a mi tiempo de vida de los guiones que he programado). Esto se está convirtiendo en una solución frecuente para mí en el medio silvestre.



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

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

La mejor manera de matar a la ejecución de scripts Bash de Cygwin está utilizando el Sysinternals herramienta PsKill64.exe. La razón es que ps de Cygwin también dan de PID que son diferentes de WINPID.

Además, pskill también tiene la bandera -t que mata a todo el árbol de procesos, lo que significa que cualquier otro hilos / subprocesos que su script puede haber comenzado. Por supuesto kill -9 <PID> también funciona, pero no mata a los descendientes ya iniciadas por el script.

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

Ahora corre 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 guión bash principal y el hilo del sueño. Así que si kill -1 8132 el hilo del sueño continuará funcionando, pero si se utiliza pskill64 -t 8132, que matará a todos sus descendientes también. Análoga al comando Linux killall.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top