تحويل PID Cygwin إلى Windows PID
-
16-09-2019 - |
سؤال
لدي عملية تفرخ مع cygwin. Script Shell، وأنا غير قادر على قتله مع kill
أمر. حتى مع cygwin kill. مع ال -f
الخيار، أحصل على هذه الرسالة:
kill: couldn't open pid 1234
أود أن أحاول قتله pskill., ، لكن لا يمكنني العثور على طريقة لتحويل Cygwin PID
إلى أ Windows PID
الذي - التي PsKill
سوف نفهم. كيف أقوم بذلك؟
المحلول
هل حاولت تشغيل قتل cygwin بدلا من المدمج باش؟ إذا كان Windows PID ثم اكتب:
/bin/kill -f 1234
أو إذا كان pid cygwin ثم اكتب:
/bin/kill -9 1234
بقدر ما أعرف أنه لا يوجد API إلى Cygwin الذي يمكنك الاتصال به لترجمة PID Cygwin إلى PID Windows. ومع ذلك، يمكنك تحليل إخراج ps -W
للقيام بالتحويل. أو، إذا كنت حقا، لا تريد حقا القيام بذلك، فاحصل على إلقاء نظرة على التعليمات البرمجية المصدرية لل Cygwin ps
الأمر، ونرى أين يحصلون على pids من. cygwin. رمز المصدر PS هنا.. وبعد يمكنك كتابة أداة مساعدة صغيرة في C لاتخاذ PID Cygwin وتعطيك PID Windows.
نصائح أخرى
ps -W
سوف تظهر Windows PID بالإضافة إلى PID Cygwin.
أو يمكنك القيام بذلك برمجيا مثل هذا:
#include <sys/cygwin.h>
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);
ال نظام ملفات بروك لديه pid ويندوز ل cygwin pid $ pid في /proc/$pid/winpid
.
> notepad&
[1] 11716
> taskkill /f /pid $(</proc/$!/winpid)
ERFOLGREICH: Der Prozess mit PID 11976 wurde beendet.
[1]+ Exit 1 notepad
هذا يعمل في sh shell:
./${Z_BIN} &
Z_PID=$!
Z_PIDW=`ps -p ${Z_PID} | awk -e '/^[[:space:]]+[[:digit:]+]/{print $4}'`
z_bin يحتوي على برنامجك لتنفيذه. سيحتوي Z_PID على PID Cygwin وسيحتوي Z_PIDW على Windows PID لنفس البرنامج. يمكنك حفظ z_pidw في ملف PID واستخدامه لاحقا لقتل أو أي غرض آخر.
لقد بحثت على الويب لمعرفة ما إذا كان لدى أي شخص وظيفة أو برنامج نصي لتحويل Cygwin Pids إلى Microsoft PIDS. لم أجد شيئا؛ لذلك جعلت بلدي. أنا أضعه هنا للحصول على حفظ آمنة (عندما لا أستطيع الوصول إلى حياتي من البرامج النصية التي قمت برمجتها). هذا أصبح حلا متكررا بالنسبة لي في البرية.
#!/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}
استخدم واصف الملف عند الاستمتاع والاستخدام بدلا من هذا الأنابيب.
أفضل طريقة لقتل البرامج النصية الجارية من Cygwin تستخدم sysinternals. أداة PsKill64.exe
. وبعد السبب هو أن Cygwin's ps
أيضا إعطاء PID هذا يختلف عن WINPID
.
بالإضافة الى، pskill
لديه أيضا -t
العلم الذي يقتل شجرة العملية بأكملها، مما يعني أي خيوط أخرى / عمليات فرعية قد بدأت النصي الخاص بك قد بدأت. بالطبع بكل تأكيد kill -9 <PID>
يعمل أيضا، لكنها لا تقتل أحفاد بدأت بالفعل من قبل البرنامج النصي.
# cat sleeper.sh
ZID=$$
WINPID=$(cat /proc/${ZID}/winpid)
echo "WINPID: ${WINPID}"
sleep 10
تعمل الآن مع:
$ ./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
كما ترى، هذا يبدأ عمليين، الرئيسي bash
البرنامج النصي وخيط النوم. لذلك إذا كنت kill -1 8132
سوف يستمر مؤشر ترابط النوم قيد التشغيل، ولكن إذا كنت تستخدم pskill64 -t 8132
, ، سوف تقتل كل أحفادها أيضا. مماثلة ل Linux killall
أمر.