سؤال

لدي عملية تفرخ مع 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 أمر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top