Question

J'ai un processus que je Spawn avec un Cygwin script shell, et je suis incapable de le tuer avec la commande kill. Même avec le Cygwin tuer avec l'option -f, Je reçois ce message:

kill: couldn't open pid 1234

Je voudrais essayer de le tuer avec PsKill , mais je ne peux pas trouver un moyen de convertir le Cygwin PID à un Windows PID qui PsKill comprendra. Comment puis-je faire?

Était-ce utile?

La solution

Avez-vous essayé de courir le tuer Cygwin au lieu de la commande interne bash? S'il est un PID de Windows puis tapez:

/bin/kill -f 1234

ou si elle est un PID Cygwin puis taper:

/bin/kill -9 1234

Pour autant que je sais qu'il n'y a pas API pour Cygwin que vous pourriez appeler pour traduire un PID Cygwin à un PID de Windows. Cependant, vous pouvez analyser la sortie de ps -W pour effectuer la conversion. Ou, si vous avez vraiment, ne voulez vraiment pas faire cela, alors jetez un oeil au code source pour la commande ps Cygwin, et voir où ils obtiennent les pid de. Le Cygwin code source ps est ici. . Vous pouvez écrire un petit utilitaire en C pour prendre la Cygwin pid et vous donner un pid de Windows.

Autres conseils

ps -W affiche le PID de Windows en plus du PID Cygwin.

Ou, vous pouvez le faire par programme comme celui-ci:

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

Le proc a les fenêtres PID pour PID Cygwin $ pid en /proc/$pid/winpid.

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

Cela fonctionne shell sh:

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

Z_BIN contient votre programme à exécuter. Z_PID contiendra Cygwin pid et Z_PIDW contiendra des fenêtres pid pour le même programme. Vous pouvez enregistrer Z_PIDW dans un fichier pid et de l'utiliser plus tard pour tuer ou à toute autre fin.

Je cherché sur le web pour voir si quelqu'un avait une fonction ou d'un script pour convertir Cygwin à Microsoft PIDs PIDs. J'ai trouvé aucune; donc j'ai fait moi-même. Je le mets ici en lieu sûr (quand je n'ai pas accès à ma vie en temps de scripts que je l'ai programmé). Cela devient une solution fréquente pour moi dans la nature.



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

descripteur de fichier utiliser lorsque vous pouvez et utiliser au lieu de ce tuyau.

La meilleure façon de tuer exécuter des scripts Bash de Cygwin utilise le Sysinternals outil PsKill64.exe. La raison en est que la ps Cygwin également donner des PID de qui sont différentes de WINPID.

En outre, pskill a aussi le drapeau -t qui tue l'ensemble de l'arbre de processus, ce qui signifie que tous les autres threads / sous-processus que votre script peut avoir commencé. Bien sûr kill -9 <PID> fonctionne aussi, mais il ne tue pas les descendants déjà commencé par le script.

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

Exécuter maintenant avec:

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

Comme vous le voyez, cela commence deux processus, le principal script bash et le fil du sommeil. Donc, si vous kill -1 8132 le fil de sommeil continuera à fonctionner, mais si vous utilisez pskill64 -t 8132, vous tuer tous ses descendants aussi. Analogue à la commande killall linux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top