it-swarm.com.de

Linux/Unix-Befehl, um festzustellen, ob der Prozess ausgeführt wird?

Ich benötige einen plattformunabhängigen (Linux/Unix | OSX) Shell/bash-Befehl, der ermittelt, ob ein bestimmter Prozess ausgeführt wird. z.B. mysqld, httpd... Was ist der einfachste Weg/Befehl, um dies zu tun?

86
Highway of Life

Obwohl pidof und pgrep ein hervorragendes Werkzeug zur Ermittlung des laufenden Betriebs sind, sind beide auf einigen Betriebssystemen leider nicht verfügbar. Ein sicherer Fail-Safe wäre folgende Verwendung: ps cax | grep command

Die Ausgabe unter Gentoo Linux:

14484? S 0:00 Apache2 
 14667? S 0:00 Apache2 
 19620? Sl 0:00 Apache2 
 21132? Ss 0:04 Apache2 

Die Ausgabe unter OS X:

42582 ?? Z 0: 00,00 (smbclient) 
 46529 ?? Z 0: 00,00 (smbclient) 
 46539 ?? Z 0: 00,00 (smbclient) 
 46547 ?? Z 0: 00,00 (smbclient) 
 46586 ?? Z 0: 00,00 (smbclient) 
 46594 ?? Z 0: 00,00 (smbclient) 

Unter Linux und OS X gibt grep einen Exit-Code zurück, sodass Sie leicht überprüfen können, ob der Prozess gefunden wurde oder nicht.

#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

Wenn Sie außerdem die Liste der PIDs erhalten möchten, können Sie diese auch leicht eingeben:

ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'

Dieser Ansatz eignet sich zum Schreiben eines einfachen leeren Zeichenfolge-Tests und zum Durchlaufen der ermittelten PIDs.

#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
  echo "Process not running." 1>&2
  exit 1
else
  for PID in $PIDS; do
    echo $PID
  done
fi

Sie können es testen, indem Sie es in einer Datei (mit dem Namen "running") mit Ausführungsberechtigungen (chmod + x running) speichern und mit einem Parameter ausführen: ./running "httpd"

#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

WARNUNG!!!

Bitte beachten Sie, dass Sie lediglich die Ausgabe von ps ax parsen, was bedeutet, dass dies, wie in der Linux-Ausgabe zu sehen ist, nicht einfach auf Prozesse abgestimmt ist, sondern auch die Argumente, die an dieses Programm übergeben werden. Ich empfehle dringend, so spezifisch wie möglich zu sein, wenn diese Methode verwendet wird (z. B. passt ./running "mysql" auch zu 'mysqld'-Prozessen). Ich empfehle dringend, which zu verwenden, um nach Möglichkeit einen vollständigen Pfad zu überprüfen.


Verweise:

http://linux.about.com/od/commands/l/blcmdl1_ps.htm

http://linux.about.com/od/commands/l/blcmdl1_grep.htm

158
Caleb Gray

Sie sollten die PID kennen!

Das Finden eines Prozesses durch den Versuch, eine Art Mustererkennung für die Prozessargumente (wie pgrep "mysqld") durchzuführen, ist eine Strategie, die früher oder später zum Scheitern verurteilt ist. Was ist, wenn Sie zwei mysqld laufen haben? Vergiss diesen Ansatz. Sie können es vielleicht vorübergehend richtig machen und es kann für ein oder zwei Jahre funktionieren, aber dann passiert etwas, worüber Sie nicht nachgedacht haben.

Nur die Prozess-ID (PID) ist wirklich eindeutig.

Speichern Sie die PID immer, wenn Sie etwas im Hintergrund starten. In Bash kann dies mit der $!-Bash-Variablen erfolgen. Sie sparen sich SO damit viel Ärger.

Wie kann ich feststellen, ob der Prozess läuft (per pid)?

Nun stellt sich die Frage, wie man weiß, ob eine PID läuft.

Einfach machen:

 ps -o pid = -p <pid> 

Dies ist POSIX und somit portabel. Die PID wird zurückgegeben, wenn der Prozess ausgeführt wird, oder nichts, wenn der Prozess nicht ausgeführt wird. Genau genommen gibt der Befehl eine einzige Spalte zurück, die pid. Da wir jedoch einen leeren Titelheader angegeben haben (der Stoff, der unmittelbar vor dem Gleichheitszeichen steht), und dies ist die einzige angeforderte Spalte, wird der Befehl ps überhaupt keinen Header verwenden . Was wir wollen, weil es das Parsing einfacher macht.

Dies funktioniert unter Linux, BSD, Solaris usw.

Eine andere Strategie wäre, den Exit-Wert des obigen ps-Befehls zu testen. Es sollte Null sein, wenn der Prozess läuft, und nicht Null, wenn dies nicht der Fall ist. Die POSIX-Spezifikation besagt, dass ps> 0 beendet werden muss, wenn ein Fehler aufgetreten ist, aber mir ist unklar, was "ein Fehler" ist. Daher verwende ich diese Strategie nicht persönlich, obwohl ich mir ziemlich sicher ist, dass sie auch auf allen Unix/Linux-Plattformen funktioniert.

24
peterh

Bei den meisten Linux-Distributionen können Sie pidof (8) verwenden.

Es werden die Prozess-IDs aller laufenden Instanzen angegebener Prozesse oder nichts gedruckt, wenn keine Instanzen ausgeführt werden.

Zum Beispiel auf meinem System (ich habe vier Instanzen von bashund eine Instanz von remmina, die ausgeführt wird):

$ pidof bash remmina
6148 6147 6144 5603 21598

Auf anderen Unices erreichen pgrep oder eine Kombination aus ps und grep dasselbe, wie andere zu Recht darauf hingewiesen haben.

13

Der einfachste Weg ist die Verwendung von ps und grep:

command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
    echo "Command is running"
else
    echo "Command is not running"
fi

Wenn Ihr Befehl einige Befehlsargumente hat, können Sie nach 'grep $ command' auch mehr 'grep cmd_arg1' einfügen, um andere mögliche Prozesse herauszufiltern, die Sie nicht interessieren.

Beispiel: Zeigen Sie mir einen Java-Prozess mit angegebenem Argument: 

-Djava.util.logging.config.file = logging.properties

läuft

ps ax | grep -v grep | grep Java | grep Java.util.logging.config.file=logging.properties | wc -l
6
Pawel Solarski

Dies sollte auf den meisten Varianten von Unix, BSD und Linux funktionieren:

PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep

Getestet am:

  • SunOS 5.10 [daher der PATH=...]
  • Linux 2.6.32 (CentOS)
  • Linux 3.0.0 (Ubuntu)
  • Darwin 11.2.0
  • FreeBSD 9.0-STABLE
  • Red Hat Enterprise Linux ES Version 4 
  • Red Hat Enterprise Linux Server Version 5
6
Johnsyweb

Wenn ich die verschiedenen Vorschläge zusammenfasse, ist die sauberste Version, die ich gefunden habe (ohne unzuverlässiges grep, die Teile von Wörtern auslöst):

kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

kill -0 beendet den Prozess nicht, sondern prüft, ob er existiert, und gibt dann true zurück. Wenn auf Ihrem System kein pidof vorhanden ist, speichern Sie die pid, wenn Sie den Prozess starten:

$ mysql &
$ echo $! > pid_stored

dann im Skript:

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
5
gletscher

Nur ein kleiner Zusatz: Wenn Sie das -c-Flag zu ps hinzufügen, müssen Sie die Zeile, die den grep-Prozess enthält, nicht anschließend mit grep -v entfernen. Das heißt.

ps acux | grep cron

sie benötigen nur ein typisches bsd-ish-System (einschließlich MacOSX). Sie können den -u weglassen, wenn Sie weniger Informationen benötigen.

In einem System, in dem die Genetik des nativen ps-Befehls auf SysV verweist, würden Sie dies verwenden

ps -e |grep cron

oder

ps -el |grep cron 

für eine Auflistung, die mehr als nur PID und Prozessnamen enthält. Natürlich können Sie die speziellen Felder zum Ausdrucken mit der Option -o <field,field,...> auswählen.

5
Tatjana Heuser

Ich benutze pgrep -l httpd, bin aber nicht sicher, ob es auf einer Plattform vorhanden ist ... 
Wer kann unter OSX bestätigen?

3
olibre

Sie sollten die PID Ihres Prozesses kennen.

Wenn Sie es starten, wird seine PID in der Variable $! aufgezeichnet. Speichern Sie diese PID in einer Datei.

Dann müssen Sie prüfen, ob diese PID einem laufenden Prozess entspricht. Hier ist ein komplettes Skelett-Skript:

FILE="/tmp/myapp.pid"

if [ -f $FILE ];
then
   PID=$(cat $FILE)
else
   PID=1
fi

ps -o pid= -p $PID
if [ $? -eq 0 ]; then
  echo "Process already running."  
else
  echo "Starting process."
  run_my_app &
  echo $! > $FILE
fi

Basierend auf der Antwort von peterh. Der Trick, um zu wissen, ob eine bestimmte PID ausgeführt wird, liegt in der ps -o pid= -p $PID-Anweisung.

1
icarito

Keine der Antworten funktionierte für mich, also meine:

process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
  echo "Process is not running."
else
  echo "Process is running."
fi

Erläuterung:

|tr -d '\n'

Dadurch wird der vom Terminal erstellte Wagenrücklauf entfernt. Der Rest kann durch this post erklärt werden.

0
Jeff Luyet

Dieser Ansatz kann verwendet werden, wenn die Befehle 'ps', 'pidof' und rest nicht zur Verfügung stehen .. Ich persönlich benutze procfs sehr häufig in meinen Tools/Skripts/Programmen.

   egrep -m1  "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3

Kleine Erklärung was los ist:

  1. -m1 - Prozess beim ersten Spiel anhalten
  2. "mysqld $ | httpd $" - grep stimmt mit Zeilen überein, die auf mysqld OR httpd enden
  3. / proc/[0-9] * - bash stimmt mit der Zeile überein, die mit einer beliebigen Nummer beginnt
  4. ausschneiden - teilen Sie einfach die Ausgabe nach dem Trennzeichen '/' und extrahieren Sie das Feld 3
0
Tom Lime

Dies gibt die Anzahl der Prozesse aus, deren Basisname "Chrom-Browser" ist:

ps -e -o args= | awk 'BEGIN{c=0}{
 if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
 if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"

Wenn "0" ausgegeben wird, läuft der Prozess nicht. Der Befehl setzt voraus, dass der Prozesspfad kein Leerzeichen enthält. Ich habe dies nicht mit suspendierten Prozessen oder Zombie-Prozessen getestet.

Getestet mit gwak als awk-Alternative in Linux.

Hier ist eine vielseitigere Lösung mit einigen Anwendungsbeispielen:

#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
 local quiet=1;
 shift
else
 local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
 name=$2
 if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
 if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}

process='chromium-browser'

printf "Process \"${process}\" is "
if isProcessRunning -q "$process" 
 then printf "running.\n"
 else printf "not running.\n"; fi

printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"
0
jarno

Hier ist meine Version. Eigenschaften:

  • sucht nach exakten Programmnamen (erstes Argument der Funktion). Suche nach "mysql" stimmt nicht mit dem Ausführen von "mysqld" überein
  • sucht nach Programmargumenten (zweites Argument der Funktion)

skript:

#!/bin/bash

# $1 - cmd
# $2 - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
    for i in $(pidof $1); do
        cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null
        if [ $? -eq 0 ]; then
            return 0
        fi
    done
    return 1
}

isRunning Java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
    echo "not running, starting..."
fi
0
Raigedas