2009-11-05 6 views
7

Cygwinシェルスクリプトを使用してプロセスを作成しましたが、killコマンドでそれを強制終了できません。でも-fオプション付きCygwin killで、私はこのメッセージを得る:CygwinのPIDをWindowsのPIDに変換する

kill: couldn't open pid 1234 

を私はPsKillでそれを殺すために試してみたいが、私はPsKillが理解Windows PIDCygwin PIDを変換する方法を見つけることができません。どうやってやるの?

答えて

10

bash組み込みの代わりにcygwin killを実行しようとしましたか?それはWindowsのPIDである場合には次のように入力します。

/bin/kill -f 1234 

か、CygwinのPIDの場合は次のように入力します。

/bin/kill -9 1234 

を限り、私はあなたが変換するために呼び出すことができるとのCygwinへのAPIがありません知っているようにCygwinのPIDをWindowsのPIDに変換します。ただし、変換を行うには、ps -Wの出力を解析することができます。あるいは、本当にそれをやりたくないのであれば、Cygwin psコマンドのソースコードを見て、どこからpidを入手するかを見てください。 Cygwin ps source code is here.。 Cygwinのpidを取得し、Windowsのpidを与えるために、Cで小さなユーティリティを書くことができます。

+0

はい、それは私が使っているCygwinのkillです。私は/ bin/kill -f -9 1234と/ bin/kill -9 1234を成功させました。 1234はCygwin PIDです。 – Jazz

+2

-fを使用する場合、ps -W –

+1

からWindows PIDを与えるべきです。この素晴らしい答えは別として、プロセスがWindowsの内側からロックされている場合、Cygwinのkillは "could not open pid 1234"というメッセージを生成します。このプロセスはWindowsの内部から最初にアンロックする必要があります。 – Secko

6

ps -WはCygwin PIDに加えてWindows PIDを表示します。

それとも、あなたはこのようにプログラム的にそれを行うことができます。

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

はい、私は知っていますが、私はpsの出力を解析する代わりにこれを行う直接的な方法を望んでいました。 – Jazz

+0

プログラムによる代替方法を追加 –

1

これは、shシェルで動作します:

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

Z_BINは、実行するプログラムが含まれています。 Z_PIDにはcygwin pidが含まれ、Z_PIDWには同じプログラムのpidが含まれます。 Z_PIDWをpidファイルに保存し、後で殺したり他の目的に使用することができます。

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} 

使用ファイルディスクリプタ。

+0

文法とコピー+ペーストのテキストが誤って解釈されてしまいました。しかし、私のstackexhange.com jujitsuは素晴らしいことではありません。私は出ている。 – MyMightyJoeYoung

2

proc file systemには、cygwin PID $ 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 
+0

これは本当に正しい方法です! – not2qubit

0

のCygwinから実行しているbashのスクリプトを殺すための最良の方法は、SysinternalsツールPsKill64.exeを使用しています。理由は、CygwinのpsWINPIDとは異なる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 

、この2つのプロセス、メインbashスクリプトと睡眠スレッドを開始します。したがって、kill -1 8132の場合、スリープスレッドは継続して実行されますが、pskill64 -t 8132を使用すると、その子孫もすべて終了します。 linux killallコマンドに似ています。