Konvertieren Sie eine Cygwin -PID in eine Windows -PID
-
16-09-2019 - |
Frage
Ich habe einen Prozess, den ich mit einem laichen Cygwin Shell -Skript, und ich kann es nicht mit dem töten kill
Befehl. Auch mit dem Cygwin Kill mit dem -f
Option, ich erhalte diese Nachricht:
kill: couldn't open pid 1234
Ich würde gerne versuchen, es zu töten Pkill, aber ich kann keinen Weg finden, um das zu konvertieren Cygwin PID
zu einem Windows PID
das PsKill
wird verstehen. Wie kann ich das machen?
Lösung
Haben Sie versucht, den Cygwin -Kill anstelle des bauten Bashs zu laufen? Wenn es sich um eine Windows -PID handelt, dann geben Sie:
/bin/kill -f 1234
oder wenn es sich um eine Cygwin -PID handelt, dann tippen Sie:
/bin/kill -9 1234
Soweit ich weiß, gibt es keine API zu Cygwin, die Sie anrufen können, um eine Cygwin -PID in eine Windows -PID zu übersetzen. Sie könnten jedoch die Ausgabe von analysieren ps -W
Um die Konvertierung durchzuführen. Oder, wenn Sie das wirklich nicht tun wollen, dann schauen Sie sich den Quellcode für den Cygwin an ps
Befehl und sehen Sie, woher sie die Pids bekommen. Der Cygwin PS -Quellcode ist da.. Sie können ein kleines Dienstprogramm in C schreiben, um die Cygwin -PID zu nehmen und Ihnen eine Windows -PID zu geben.
Andere Tipps
ps -W
Zeigt die Windows -PID zusätzlich zum Cygwin PID an.
Oder Sie können es programmgesteuert wie folgt:
#include <sys/cygwin.h>
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);
Das Proc -Dateisystem Hat die Windows PID für Cygwin Pid $ pid in /proc/$pid/winpid
.
> notepad&
[1] 11716
> taskkill /f /pid $(</proc/$!/winpid)
ERFOLGREICH: Der Prozess mit PID 11976 wurde beendet.
[1]+ Exit 1 notepad
Dies funktioniert in SH Shell:
./${Z_BIN} &
Z_PID=$!
Z_PIDW=`ps -p ${Z_PID} | awk -e '/^[[:space:]]+[[:digit:]+]/{print $4}'`
Z_BIN enthält Ihr Programm zur Ausführung. Z_PID enthält Cygwin PID und Z_PIDW enthält Windows PID für dasselbe Programm. Sie können Z_PIDW in einer PID -Datei speichern und später zum Töten oder einem anderen Zweck verwenden.
Ich habe im Web gesucht, um festzustellen, ob jemand eine Funktion oder ein Skript hatte, um Cygwin -Pids in Microsoft PIDs umzuwandeln. Ich fand keine; Also habe ich meine eigenen gemacht. Ich stelle es hier zur sicheren Aufbewahrung auf (wenn ich keinen Zugang zu meiner Lebenszeit von Skripten habe, die ich programmiert habe). Dies wird für mich in freier Wildbahn zu einer häufigen Lösung.
#!/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}
Verwenden Sie den Dateideskriptor, wenn Sie können, und verwenden Sie anstelle dieses Rohrs.
Der beste Weg, um laufende Bash -Skripte von Cygwin zu töten, ist die Verwendung des SYSINTERNALS Werkzeug PsKill64.exe
. Der Grund ist, dass Cygwin's ps
Geben Sie auch PIDs, die sich von unterschiedlich unterscheiden WINPID
.
Zusätzlich, pskill
hat auch das -t
Flagge, die den gesamten Prozessbaum tötet, was andere Threads/Unterprozesse bedeutet, die Ihr Skript möglicherweise begonnen hat. Na sicher kill -9 <PID>
funktioniert auch, aber es tötet keine Nachkommen, die bereits vom Drehbuch gestartet wurden.
# cat sleeper.sh
ZID=$$
WINPID=$(cat /proc/${ZID}/winpid)
echo "WINPID: ${WINPID}"
sleep 10
Jetzt rennen mit:
$ ./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
Wie Sie sehen, startet dies zwei Prozesse, das Haupt bash
Skript und der Schlaf -Thread. Also wenn du kill -1 8132
Der Schlaffaden läuft weiter, aber wenn Sie verwenden pskill64 -t 8132
, Sie werden auch alle Nachkommen töten. Analog zum Linux killall
Befehl.