it-swarm.com.de

So prüfen Sie, ob eine Prozess-ID (PID) vorhanden ist

In einem Bash-Skript möchte ich Folgendes tun (in Pseudo-Code):

if [ a process exists with $PID ]; then

    kill $PID 

fi

Was ist der passende Ausdruck für die Bedingungsanweisung?

149
Richard H

Um zu prüfen, ob ein Prozess vorhanden ist, verwenden Sie

kill -0 $pid

Aber so wie @unwind gesagt hat, wenn du es sowieso töten willst, einfach

kill $pid

oder du wirst eine Wettkampfbedingung haben.

Wenn Sie die Textausgabe von kill ignorieren und basierend auf dem Beendigungscode etwas tun möchten, können Sie dies tun

if ! kill $pid > /dev/null 2>&1; then
    echo "Could not send SIGTERM to process $pid" >&2
fi

Der beste Weg ist:

if ps -p $PID > /dev/null
then
   echo "$PID is running"
   # Do something knowing the pid exists, i.e. the process with $PID is running
fi

Das Problem mit:

kill -0 $PID

der Exit-Code ist nicht Null, auch wenn die PID läuft und Sie keine Erlaubnis haben, sie zu beenden. Zum Beispiel:

kill -0 1

und 

kill -0 $non-running-pid

haben einen nicht unterscheidbaren (von Null verschiedenen) Exit-Code für einen normalen Benutzer, aber der Init-Prozess (PID 1) läuft sicherlich.

DISKUSSION

Die Antworten zu den Kill- und Race-Bedingungen sind genau richtig, wenn der Testkörper ein "Kill" ist. Ich bin auf der Suche nach dem allgemeinen " wie teste ich auf eine PID-Existenz in bash ". 

Die/proc-Methode ist interessant, aber in gewissem Sinne unterbricht der Geist der Abstraktion des Befehls "ps", d. H.

220
FDS
if [ -n "$PID" -a -e /proc/$PID ]; then
    echo "process exists"
fi

oder

if [ -n "$(ps -p $PID -o pid=)" ]

In der letzteren Form ist -o pid= ein Ausgabeformat, um nur die Prozess-ID-Spalte ohne Kopfzeile anzuzeigen. Die Anführungszeichen sind notwendig für den nicht leeren Zeichenfolgenoperator -n, um ein gültiges Ergebnis zu erhalten.

55
user2683246

Der Befehl ps mit -p $PID kann dies tun:

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs
30
oherrala

Sie haben zwei Möglichkeiten:

Beginnen wir mit der Suche nach einer bestimmten Anwendung in meinem Laptop:

[[email protected]:~]# ps fax | grep mozilla
 3358 ?        S      0:00  \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2    S+     0:00              \_ grep mozilla

In allen Beispielen wird jetzt nach PID 3358 gesucht.

Erster Weg : Führen Sie "ps aux" und grep für die PID in der zweiten Spalte aus. In diesem Beispiel suche ich nach Firefox und dann nach der PID:

[[email protected]:~]# ps aux | awk '{print $2 }' | grep 3358
3358

Ihr Code lautet also:

if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
    kill $PID 
fi

Zweiter Weg : Suchen Sie einfach etwas im /proc/$PID-Verzeichnis. Ich verwende "exe" in diesem Beispiel, aber Sie können alles andere verwenden.

[[email protected]:~]# ls -l /proc/3358/exe 
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash

Ihr Code lautet also:

if [ -f /proc/$PID/exe ]; then
    kill $PID 
fi

BTW: was ist los mit kill -9 $PID || true?


BEARBEITEN:

Nachdem ich ein paar Monate darüber nachgedacht habe ... (ungefähr 24 ...), ist die ursprüngliche Idee, die ich hier gegeben habe, ein Nizza-Hack, aber höchst unporträtierbar. Während es einige Implementierungsdetails von Linux vermittelt, funktioniert es unter Mac, Solaris oder * BSD nicht. Es kann sogar bei zukünftigen Linux-Kerneln fehlschlagen. Bitte verwenden Sie "ps" wie in anderen Antworten beschrieben.

10
elcuco

Ich denke, das ist eine schlechte Lösung, die sich für die Rennbedingungen öffnet. Was ist, wenn der Prozess zwischen Ihrem Test und Ihrem Aufruf zum Töten aufhört? Dann wird das Töten fehlschlagen. Warum also nicht einfach den Kill in allen Fällen versuchen und den Rückgabewert überprüfen, um herauszufinden, wie es gelaufen ist?

7
unwind

Es scheint, als ob Sie wollen

wait $PID

die zurückgegeben wird, wenn $pid beendet ist.

Ansonsten können Sie verwenden

ps -p $PID

Überprüfen Sie, ob der Prozess noch aktiv ist (dies ist effektiver als kill -0 $pid, da er auch dann funktioniert, wenn Sie die PID nicht besitzen).

3
Gagan Gami

In GNU/Linux können Sie beispielsweise Folgendes verwenden:

Pid=$(pidof `process_name`)

if [ $Pid > 0 ]; then

   do something
else

   do something
fi 

Oder so ähnlich

Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN

und das zeigt Ihnen den Namen der App, nur den Namen ohne ID.

0
inukaze

der folgende Code prüft, ob mein Prozess ausgeführt wird, wenn dies nicht der Fall ist.

lassen Sie uns neue Nachrichten nur von Amazon SQS stündlich prüfen, und nur, wenn der Prozess nicht ausgeführt wird.

#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
    /usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
    echo "do nothing, just smile =)"
fi
exit $?
0
Brian Sanchez

hier speichere ich die PID in einer Datei namens .pid (was wie/run/... ist) und führe das Skript nur dann aus, wenn es nicht bereits ausgeführt wird.

#!/bin/bash
if [ -f .pid ]; then
  read pid < .pid
  echo $pid
  ps -p $pid > /dev/null
  r=$?
  if [ $r -eq 0 ]; then
    echo "$pid is currently running, not executing $0 twice, exiting now..."
    exit 1
  fi
fi

echo $$ > .pid

# do things here

rm .pid

Anmerkung: Es gibt eine Racebedingung, da nicht überprüft wird, wie die PID aufgerufen wird. Wenn das System neu gestartet wird und .pid vorhanden ist, aber von einer anderen Anwendung verwendet wird, kann dies zu unvorhergesehenen Konsequenzen führen.

0
invalidmagic