2009-11-05 32 views
7

Tôi có một quá trình tôi sinh ra với một tập lệnh shell Cygwin và tôi không thể giết nó bằng lệnh kill. Ngay cả với Cygwin kill với các tùy chọn -f, tôi nhận được tin nhắn này:Chuyển đổi một Cygwin PID sang Windows PID

kill: couldn't open pid 1234 

Tôi muốn cố gắng để giết nó với PsKill, nhưng tôi không thể tìm thấy một cách để chuyển đổi các Cygwin PID đến một Windows PID rằng PsKill sẽ hiểu. Làm thế nào tôi có thể làm điều đó?

Trả lời

10

Bạn đã thử chạy trình diệt Cygwin thay vì xây dựng bash? Nếu nó là một Windows PID sau đó gõ:

/bin/kill -f 1234 

hoặc nếu nó là một Cygwin PID sau đó gõ:

/bin/kill -9 1234 

Theo như tôi biết không có API để Cygwin rằng bạn có thể gọi đến dịch một Cygwin PID đến một Windows PID. Tuy nhiên, bạn có thể phân tích đầu ra của ps -W để thực hiện chuyển đổi. Hoặc, nếu bạn thực sự, thực sự không muốn làm điều đó, sau đó có một cái nhìn tại mã nguồn cho lệnh Cygwin ps, và xem nơi họ nhận được các pids từ. The Cygwin ps source code is here.. Bạn có thể viết một tiện ích nhỏ trong C để lấy Cygwin pid và cung cấp cho bạn một pid Windows.

+0

Vâng, đó là lệnh giết Cygwin mà tôi đang sử dụng. Tôi đã thử/bin/kill -f -9 1234 và/bin/kill -9 1234 không thành công. 1234 là một Cygwin PID. – Jazz

+2

Nếu bạn sử dụng -f, sau đó bạn nên cung cấp cho nó các PID Windows từ ps -W –

+1

Ngoài câu trả lời tuyệt vời này - đôi khi khi quá trình bị khóa từ bên trong Windows, Cygwin giết sinh sản "không thể mở pid 1234" tin nhắn. Quá trình sau đó cần phải được mở khóa từ bên trong Windows đầu tiên. – Secko

6

ps -W sẽ hiển thị PID của Windows cùng với Cygwin PID.

Hoặc, bạn có thể làm điều đó theo chương trình như thế này:

#include <sys/cygwin.h> 
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid); 
+0

Vâng, tôi biết, nhưng tôi đã hy vọng một cách trực tiếp để làm điều này thay vì phân tích cú pháp đầu ra ps. – Jazz

+0

Đã thêm chương trình thay thế –

1

này hoạt động trong vỏ sh:

./${Z_BIN} & 
Z_PID=$! 
Z_PIDW=`ps -p ${Z_PID} | awk -e '/^[[:space:]]+[[:digit:]+]/{print $4}'` 

Z_BIN chứa chương trình của bạn để thực thi. Z_PID sẽ chứa cygwin pid và Z_PIDW sẽ chứa các cửa sổ pid cho cùng một chương trình. Bạn có thể lưu Z_PIDW vào một tệp pid và sử dụng nó sau này để giết hoặc bất kỳ mục đích nào khác.

0

Tôi đã tìm kiếm trên web để xem có ai có chức năng hoặc tập lệnh để chuyển đổi các cygwin PID thành Microsoft PID không. Tôi không tìm thấy; nên tôi tự làm. Tôi đặt nó lên đây để giữ an toàn (khi tôi không có quyền truy cập vào các tập lệnh của mình mà tôi đã lập trình). Điều này đang trở thành một giải pháp thường xuyên cho tôi trong tự nhiên.



    #!/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} 

Sử dụng mô tả tập tin khi bạn có thể và sử dụng thay vì ống đó.

+0

Ngữ pháp và sao chép + dán văn bản bị hiểu sai ở dưới cùng ở đó. Nhưng stackexhange.com jujitsu của tôi không phải là tuyệt vời. Tôi ra ngoài. – MyMightyJoeYoung

2

proc file system có các cửa sổ PID cho cygwin PID $ pid trong /proc/$pid/winpid.

> notepad& 
[1] 11716 
> taskkill /f /pid $(</proc/$!/winpid) 
ERFOLGREICH: Der Prozess mit PID 11976 wurde beendet. 
[1]+ Exit 1     notepad 
+0

Đây thực sự là cách phù hợp để làm điều đó! – not2qubit

0

Cách tốt nhất để giết chạy script Bash từ Cygwin đang sử dụng các công cụ SysinternalsPsKill64.exe. Lý do là của Cygwin ps cũng cung cấp cho PID của là khác nhau từ WINPID.

Ngoài ra, pskill cũng có cờ -t làm mất toàn bộ cây quá trình, có nghĩa là bất kỳ luồng/quy trình phụ nào khác mà tập lệnh của bạn có thể đã bắt đầu. Tất nhiên kill -9 <PID> cũng hoạt động, nhưng nó không giết con cháu đã được bắt đầu bởi kịch bản.

# cat sleeper.sh 
ZID=$$ 
WINPID=$(cat /proc/${ZID}/winpid) 
echo "WINPID: ${WINPID}" 
sleep 10 

Bây giờ chạy với:

$ ./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 

Như bạn thấy, điều này bắt đầu hai quá trình, các bash kịch bản chính và các chủ đề giấc ngủ. Vì vậy, nếu bạn kill -1 8132 luồng ngủ sẽ tiếp tục chạy, nhưng nếu bạn sử dụng pskill64 -t 8132, bạn cũng sẽ giết tất cả các hậu duệ của nó. Tương tự như lệnh linux killall.