Commande Linux / Unix pour déterminer si le processus est en cours d'exécution?

J'ai besoin d'une commande shell/bash indépendante de la plate-forme (Linux|Unix/OSX) qui déterminera si un processus spécifique est en cours d'exécution. par exemple mysqld, httpd... Quelle est la manière/commande la plus simple de le faire?

85
demandé sur Highway of Life 2012-02-02 22:05:27

14 réponses

Alors que pidof et pgrep sont d'excellents outils pour déterminer ce qui est en cours d'exécution, ils sont tous deux, malheureusement, indisponibles sur certains systèmes d'exploitation. Un fail safe défini serait d'utiliser ce qui suit: ps cax | grep command

La sortie sur Gentoo Linux:

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

La sortie sur 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)

Sous Linux et OS X, grep renvoie un code de sortie, il est donc facile de vérifier si le processus a été trouvé ou non:

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

En Outre, si vous souhaitez la liste des pid, vous pouvez facilement grep pour ceux-ci aussi:

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

Dont la sortie est la même sur Linux et OS X:

3519 3521 3523 3524

La sortie de ce qui suit est une chaîne vide, rendant cette approche sûre pour les processus qui ne sont pas en cours d'exécution:

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

Cette approche est appropriée pour écrire un simple test de chaîne vide, puis même itérer à travers les pid découverts.

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

, Vous pouvez le tester en l'enregistrant dans un fichier (nommé "running") avec les autorisations d'exécution (chmod + x running )et l'exécution avec un paramètre: ./running "httpd"

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

Attention!!!

Gardez à l'esprit que vous analysez simplement la sortie de ps ax ce qui signifie que, comme on le voit dans la sortie Linux, elle ne correspond pas simplement aux processus, mais aussi aux arguments transmis à ce programme. Je recommande fortement d'être aussi spécifique que possible lors de l'utilisation de cette méthode (par exemple ./running "mysql" correspondra également aux processus 'mysqld'). J'ai très recommande d'utiliser which pour vérifier un chemin complet si possible.


Références:

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

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

154
répondu Caleb Gray 2012-08-08 17:32:22

Vous devriez connaître le PID !

Trouver un processus en essayant de faire une sorte de reconnaissance de formes sur le processus d'arguments (comme pgrep "mysqld") est une stratégie vouée à l'échec tôt ou tard. Que faire si vous avez deux mysqld en cours d'exécution? Oubliez cette approche. Vous pouvez le faire correctement Temporairement et cela peut fonctionner pendant un an ou deux, mais il se passe quelque chose auquel vous n'avez pas pensé.

Seul l'id de processus (pid) est vraiment unique.

Toujours stocker le pid lorsque vous lancez quelque chose dans le fond. Dans Bash, cela peut être fait avec la variable $! Bash. Vous vous épargnerez tant de problèmes en le faisant.

Comment déterminer si le processus est en cours d'exécution (par pid)

Alors maintenant la question devient Comment savoir si un pid est en cours d'exécution.

Faites simplement:

ps -o pid= -p <pid>

C'est POSIX et donc portable. Il sera de retour le pid si le processus est en cours d'exécution ou ne retournent rien si le processus n'est pas en cours d'exécution. Strictement parlant, la commande retournera un seul colonne, le pid, mais puisque nous avons donné un en-tête de titre vide (le truc précédant immédiatement le signe égal) et que c'est la seule colonne demandée, la commande ps n'utilisera pas du tout l'en-tête. C'est ce que nous voulons parce que cela rend l'analyse plus facile.

Cela fonctionnera sur Linux, BSD, Solaris, etc.

Une autre stratégie serait de tester la valeur de sortie de la commande ps ci-dessus. Il devrait être nul si le processus est en cours d'exécution et non nul si ce n'est pas le cas. la spécification POSIX dit que {[4] } doit quitter > 0 si une erreur s'est produite mais je ne sais pas ce qui constitue "une erreur". Par conséquent, je n'utilise pas Personnellement cette stratégie bien que je sois sûr que cela fonctionnera aussi bien sur toutes les plates-formes Unix/Linux.

22
répondu peterh 2013-10-03 10:53:02

Sur la plupart des distributions Linux, vous pouvez utiliser pidof(8).

Il imprimera les ID de processus de toutes les instances en cours d'exécution des processus spécifiés, ou rien s'il n'y a pas d'instances en cours d'exécution.

, Par exemple, sur mon système (j'ai quatre instances de bashet une instance de remmina en cours d'exécution):

$ pidof bash remmina
6148 6147 6144 5603 21598

Sur d'autres unités, pgrep ou une combinaison de ps et grep réalisera la même chose, comme d'autres l'ont souligné à juste titre.

13
répondu Frédéric Hamidi 2012-02-02 18:14:22

Le moyen le plus simple est d'utiliser ps et 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

Si votre commande a des arguments de commande, vous pouvez également mettre plus de 'grep cmd_arg1' après 'grep $ command' pour filtrer les autres processus possibles qui ne vous intéressent pas.

Exemple: montrez - moi si un processus java avec l'argument fourni:

-Djava.util.journalisation.config.fichier = journalisation.propriétés

Est en cours d'exécution

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l
6
répondu Pawel Solarski 2012-10-26 08:20:24

Cela devrait fonctionner sur la plupart des saveurs D'Unix, BSD et Linux:

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

Testé sur:

  • SunOS 5.10 [d'Où le 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
répondu Johnsyweb 2013-02-14 20:49:16

Juste un ajout mineur: si vous ajoutez l'indicateur -c à ps, vous n'avez pas besoin de supprimer la ligne contenant le processus grep avec grep -v par la suite. I. e.

ps acux | grep cron

Est tout le typage dont vous aurez besoin sur un système bsd-ish (Cela inclut MacOSX), vous pouvez laisser le -u Si vous avez besoin de moins d'informations.

Sur un système où la génétique de la commande native ps pointe vers SysV, vous utiliseriez

ps -e |grep cron

Ou

ps -el |grep cron 

Pour une liste contenant plus que simplement pid et process nom. Bien sûr, vous pouvez sélectionner les champs spécifiques à imprimer en utilisant l'option -o <field,field,...>.

5
répondu Tatjana Heuser 2012-02-02 21:32:45

En rassemblant les différentes suggestions, la version la plus propre que j'ai pu trouver (sans grep peu fiable qui déclenche des parties de mots) est:

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

Kill -0 ne tue pas le processus mais vérifie s'il existe et renvoie true, si vous n'avez pas pidof sur votre système, stockez le pid lorsque vous lancez le processus:

$ mysql &
$ echo $! > pid_stored

, Puis dans le script:

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
4
répondu gletscher 2014-04-04 19:20:15

J'utilise pgrep -l httpd mais je ne suis pas sûr qu'il soit présent sur n'importe quelle plate-forme...
Qui peut confirmer sur OSX?

3
répondu olibre 2012-02-02 18:10:34

Vous devez connaître le PID de votre processus.

Lorsque vous le lancez, son PID sera enregistré dans la variable $!. Enregistrez CE PID dans un fichier.

Ensuite, vous devrez vérifier si ce PID correspond à un processus en cours d'exécution. Voici un script squelette complet:

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

, Basé sur la réponse de peterh. L'astuce pour savoir si un PID donné est en cours d'exécution est dans l'instruction ps -o pid= -p $PID.

1
répondu icarito 2017-05-23 12:34:42

Cette approche peut être utilisée dans le cas où les commandes 'ps', 'pidof' et rest ne sont pas disponibles. Personnellement, j'utilise procfs très souvent dans mes outils/scripts/programmes.

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

Petite explication de ce qui se passe:

  1. - m1-arrêter le processus sur la première correspondance
  2. "mysqld$ / httpd$" - grep correspondra aux lignes qui se sont terminées sur mysqld ou httpd
  3. / proc/[0-9]* - bash correspondra à la ligne qui a commencé avec n'importe quel nombre
  4. cut-il suffit de diviser la sortie par délimiteur ' / ' et extraire le champ 3
0
répondu Tom Lime 2013-11-14 09:16:41

Affiche le nombre de processus dont le nom de base est "Chrome-browser":

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"

Si cela affiche "0", le processus n'est pas en cours d'exécution. La commande suppose que le chemin du processus ne contient pas d'espace de rupture. Je n'ai pas testé cela avec des processus suspendus ou des processus Zombies.

Testé en utilisant gwak comme alternative awk sous Linux.

Voici une solution plus polyvalente avec un exemple d'utilisation:

#!/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
répondu jarno 2015-06-21 16:25:54

Voici ma version. Caractéristiques:

  • vérifie le nom exact du programme (premier argument de la fonction). la recherche de " mysql "ne correspond pas à l'exécution de"mysqld"
  • recherche les arguments du programme (deuxième argument de la fonction)

Script:

#!/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
répondu Raigedas 2018-02-01 20:18:01

Aucune des réponses n'a fonctionné pour moi, alors voici la mienne:

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

Explication:

|tr -d '\n'

Cela supprime le retour chariot créé par le terminal. Le reste peut être expliqué par ce post.

0
répondu Jeff Luyet 2018-06-20 18:04:37

La fonction shell suivante, basée uniquement sur les commandes et options standard POSIX, devrait fonctionner sur la plupart des systèmes Unix et linux (sinon aucun). :

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "$1" "$cmd" ||
    printf "%s is not running\n\n" $1
  [ -n "$cmd" ]
}

$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd

$ isPidRunning ksh
ksh is running
5230 ksh

$ isPidRunning bash
bash is not running

Notez qu'il s'étouffe lorsqu'il passe le nom de commande douteux "0]" et ne parvient pas non plus à identifier les processus ayant un espace intégré dans leurs noms.

Notez aussi que la solution la plus votée et acceptée exige des options ps non portables et utilise gratuitement un shell qui, malgré sa popularité, ne garantie d'être présent sur toutes les machines Unix / Linux (bash)

-1
répondu jlliagre 2015-06-22 12:54:53