将Cygwin PID转换为Windows PID

时间:2009-11-05 09:24:26

标签: shell cygwin sysinternals

我有一个使用Cygwin shell脚本生成的进程,我无法使用kill命令将其删除。即使Cygwin kill带有-f选项,我也会收到以下消息:

kill: couldn't open pid 1234

我想尝试使用PsKill将其删除,但我找不到将Cygwin PID转换为Windows PID会理解的PsKill的方法。我怎么能这样做?

6 个答案:

答案 0 :(得分:10)

您是否尝试过运行cygwin kill而不是bash内置?如果是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。

答案 1 :(得分:6)

除了Cygwin PID之外,

ps -W将显示Windows PID。

或者,你可以这样编程:

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

答案 2 :(得分:3)

proc file system/proc/$pid/winpid中有cygwin PID $ pid的窗口PID。

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

答案 3 :(得分:1)

这适用于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文件中,稍后将其用于查杀或任何其他目的。

答案 4 :(得分:0)

我在网上搜索是否有人有一个功能或脚本将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}

尽可能使用文件描述符,而不是使用该管道。

答案 5 :(得分:0)

从Cygwin中杀死正在运行的Bash脚本的最佳方法是使用Sysinternals工具&{Last:bob} <nil> 。原因是Cygwin的PsKill64.exe也给出了与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 脚本和sleep线程。因此,如果你bash睡眠线程将继续运行,但如果你使用kill -1 8132,你也会杀死它的所有后代。类似于linux pskill64 -t 8132命令。