7

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

kill: couldn't open pid 1234

我想尝试用PsKill杀死它,但我找不到将它转换为Cygwin PID可以Windows PID理解PsKill的方法。我怎样才能做到这一点?

4

6 回答 6

9

您是否尝试过运行 cygwin kill 而不是 bash 内置?如果是 Windows PID,则键入:

/bin/kill -f 1234

或者如果它是 Cygwin PID,则键入:

/bin/kill -9 1234

据我所知,您可以调用 Cygwin 的 API 将 Cygwin PID 转换为 Windows PID。但是,您可以解析 的输出ps -W以进行转换。或者,如果你真的,真的不想那样做,那么看看 Cygwinps命令的源代码,看看他们从哪里得到 pid。Cygwin ps 源代码在这里。. 您可以用 C 编写一个小实用程序来获取 Cygwin pid 并为您提供 Windows pid。

于 2009-11-05T09:31:04.843 回答
9

ps -W除了 Cygwin PID 之外,还将显示 Windows PID。

或者,您可以像这样以编程方式执行此操作:

#include <sys/cygwin.h>
winpid = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, cygpid);
于 2009-11-05T09:32:49.630 回答
6

proc 文件系统具有 cygwin PID $pid in 的 windows PID /proc/$pid/winpid

> notepad&
[1] 11716
> taskkill /f /pid $(</proc/$!/winpid)
ERFOLGREICH: Der Prozess mit PID 11976 wurde beendet.
[1]+  Exit 1                  notepad
于 2017-07-01T15:45:47.260 回答
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 文件中,稍后将其用于杀戮或任何其他目的。

于 2013-11-17T02:38:58.443 回答
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}

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

于 2016-09-07T19:24:04.380 回答
0

从 Cygwin 终止正在运行的 Bash 脚本的最佳方法是使用Sysinternals工具PsKill64.exe。原因是 Cygwinps也给出了不同于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 8132sleep 线程将继续运行,但如果你使用pskill64 -t 8132,你也会杀死它的所有后代。类似于 linuxkillall命令。

于 2017-11-04T18:57:04.170 回答