我有一個我用Cygwin shell腳本生成的進程,我無法使用kill
命令將其終止。即使在Cygwin kill與-f
選擇,我得到這個消息:將Cygwin PID轉換爲Windows PID
kill: couldn't open pid 1234
我想嘗試與PsKill殺死它,但我不能找到一種方法,將Cygwin PID
轉換爲Windows PID
是PsKill
就明白了。我怎樣才能做到這一點?
我有一個我用Cygwin shell腳本生成的進程,我無法使用kill
命令將其終止。即使在Cygwin kill與-f
選擇,我得到這個消息:將Cygwin PID轉換爲Windows PID
kill: couldn't open pid 1234
我想嘗試與PsKill殺死它,但我不能找到一種方法,將Cygwin PID
轉換爲Windows PID
是PsKill
就明白了。我怎樣才能做到這一點?
你試過運行cygwin kill而不是bash builtin嗎?如果它是一個Windows PID然後鍵入:
/bin/kill -f 1234
,或者如果它是一個Cygwin的PID然後鍵入:
/bin/kill -9 1234
據我知道有Cygwin的沒有API,你可以調用翻譯一個Cygwin PID到Windows PID。但是,您可以解析ps -W
的輸出以進行轉換。或者,如果您確實不想那麼做,那麼請查看Cygwin ps
命令的源代碼,並查看它們從哪裏獲取pids。 Cygwin ps source code is here.。你可以在C編寫一個小工具來獲取Cygwin pid並給你一個Windows pid。
ps -W
除了Cygwin PID外還會顯示Windows PID。
或者,你可以做到這一點編程方式是這樣的:
#include <sys/cygwin.h>
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);
是的,我知道,但我希望有一個直接的方法來做到這一點,而不是解析ps輸出。 – Jazz
添加了編程替代 –
這個作品在sh shell中:
./${Z_BIN} &
Z_PID=$!
Z_PIDW=`ps -p ${Z_PID} | awk -e '/^[[:space:]]+[[:digit:]+]/{print $4}'`
Z_BIN包含你的程序來執行。 Z_PID將包含cygwin pid,Z_PIDW將包含同一個程序的windows pid。您可以將Z_PIDW保存到一個pid文件中,稍後將其用於查殺或其他目的。
我搜索了網絡,看看是否有人有將cygwin PID轉換爲Microsoft PID的函數或腳本。我找不到;所以我做了我自己的。我把它放在這裏是爲了保持安全(當我無法訪問我編程的腳本的生命時間時)。這對我來說是一個常見的解決方案。
#!/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}
使用的文件描述符的時候可以和使用的而不是管。
語法和複製+粘貼文本在底部被誤解釋。但我的stackexhange.com jujitsu並不好。我出去了。 – MyMightyJoeYoung
proc file system的窗口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
這的確是正確的做法! – not2qubit
最好的辦法是殺死使用Sysinternals工具PsKill64.exe
從Cygwin的運行bash腳本。原因是Cygwin的ps
也給出了與WINPID
不同的PID。
此外,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
命令。
是的,這是我正在使用的Cygwin殺人。我試過/ bin/kill -f -9 1234和/ bin/kill -9 1234,但沒有成功。 1234是一個Cygwin PID。 – Jazz
如果你使用-f,那麼你應該給它從Windows的PID PID -W –
除了這個偉大的答案 - 有時當進程被鎖定在Windows內部時,Cygwin kill會產生「無法打開pid 1234」消息。這個過程需要首先從Windows內部解鎖。 – Secko