Convertir un Cygwin PID para un PID de Windows
-
16-09-2019 - |
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?
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);
El sistema de archivos proc rel="noreferrer"> tiene las ventanas PID 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
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
.