Convertir un PID Cygwin à un PID de Windows
-
16-09-2019 - |
Question
J'ai un processus que je Spawn avec un Cygwin script shell, et je suis incapable de le tuer avec la commande kill
. Même avec le Cygwin tuer avec l'option -f
, Je reçois ce message:
kill: couldn't open pid 1234
Je voudrais essayer de le tuer avec PsKill , mais je ne peux pas trouver un moyen de convertir le Cygwin PID
à un Windows PID
qui PsKill
comprendra. Comment puis-je faire?
La solution
Avez-vous essayé de courir le tuer Cygwin au lieu de la commande interne bash? S'il est un PID de Windows puis tapez:
/bin/kill -f 1234
ou si elle est un PID Cygwin puis taper:
/bin/kill -9 1234
Pour autant que je sais qu'il n'y a pas API pour Cygwin que vous pourriez appeler pour traduire un PID Cygwin à un PID de Windows. Cependant, vous pouvez analyser la sortie de ps -W
pour effectuer la conversion. Ou, si vous avez vraiment, ne voulez vraiment pas faire cela, alors jetez un oeil au code source pour la commande ps
Cygwin, et voir où ils obtiennent les pid de. Le Cygwin code source ps est ici. . Vous pouvez écrire un petit utilitaire en C pour prendre la Cygwin pid et vous donner un pid de Windows.
Autres conseils
ps -W
affiche le PID de Windows en plus du PID Cygwin.
Ou, vous pouvez le faire par programme comme celui-ci:
#include <sys/cygwin.h>
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);
Le proc a les fenêtres PID pour PID Cygwin $ 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
Cela fonctionne shell sh:
./${Z_BIN} &
Z_PID=$!
Z_PIDW=`ps -p ${Z_PID} | awk -e '/^[[:space:]]+[[:digit:]+]/{print $4}'`
Z_BIN contient votre programme à exécuter. Z_PID contiendra Cygwin pid et Z_PIDW contiendra des fenêtres pid pour le même programme. Vous pouvez enregistrer Z_PIDW dans un fichier pid et de l'utiliser plus tard pour tuer ou à toute autre fin.
Je cherché sur le web pour voir si quelqu'un avait une fonction ou d'un script pour convertir Cygwin à Microsoft PIDs PIDs. J'ai trouvé aucune; donc j'ai fait moi-même. Je le mets ici en lieu sûr (quand je n'ai pas accès à ma vie en temps de scripts que je l'ai programmé). Cela devient une solution fréquente pour moi dans la nature.
#!/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}
descripteur de fichier utiliser lorsque vous pouvez et utiliser au lieu de ce tuyau.
La meilleure façon de tuer exécuter des scripts Bash de Cygwin utilise le Sysinternals outil PsKill64.exe
. La raison en est que la ps
Cygwin également donner des PID de qui sont différentes de WINPID
.
En outre, pskill
a aussi le drapeau -t
qui tue l'ensemble de l'arbre de processus, ce qui signifie que tous les autres threads / sous-processus que votre script peut avoir commencé. Bien sûr kill -9 <PID>
fonctionne aussi, mais il ne tue pas les descendants déjà commencé par le script.
# cat sleeper.sh
ZID=$$
WINPID=$(cat /proc/${ZID}/winpid)
echo "WINPID: ${WINPID}"
sleep 10
Exécuter maintenant avec:
$ ./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
Comme vous le voyez, cela commence deux processus, le principal script bash
et le fil du sommeil. Donc, si vous kill -1 8132
le fil de sommeil continuera à fonctionner, mais si vous utilisez pskill64 -t 8132
, vous tuer tous ses descendants aussi. Analogue à la commande killall
linux.