Comment empêcher les «ps» de signaler leur propre processus?

52
$ ps | grep django
28006 ttys004    0:01.12 /usr/bin/python bin/django celeryd --beat
51393 ttys005    0:01.45 /usr/bin/python bin/django celeryd -l INFO
51472 ttys005    0:01.29 /usr/bin/python bin/django celeryd -l INFO
51510 ttys005    0:01.89 /usr/bin/python bin/django celeryd -l INFO
51801 ttys005    0:01.83 /usr/bin/python bin/django celeryd -l INFO
53470 ttys005    0:03.97 /usr/bin/python bin/django celeryd -l INFO
53780 ttys005    0:00.00 grep django

Existe-t-il un moyen d'éviter que le dernier processus (c'est-à-dire le grep qui a été démarré en même temps que ma commande ps) soit signalé?

(J'ai commencé à essayer de créer une regex qui corresponde à la lettre, mais pas à elle-même, mais cela ne semblait pas être la bonne approche ...)

Steve Bennett
la source

Réponses:

14

Ma réponse est une variation de la réponse typique pour la recherche de "foobar" dans une psliste. L’argument de "-A" "ps"est plus portable que "aux", je crois, mais ce changement n’a aucune incidence sur la réponse. La réponse typique ressemble à ceci:

$ ps -A -ww | grep [f]oobar

Au lieu de cela, j'utilise ce modèle:

$ ps -A -ww | grep [^]]foobar

L'avantage principal est qu'il est plus facile d'écrire des scripts basés sur ces modèles, car vous concaténez simplement une chaîne statique [^]]avec le modèle que vous recherchez. Vous n'avez pas besoin de retirer la première lettre de la chaîne, de l'insérer entre les accolades puis de la concaténer à nouveau. Lors de la création de scripts dans le shell, il est plus facile de coller [^]]devant le motif recherché. Le tranchage de cordes dans Bash est une chose laide, ma variante l’évite donc. Cette variation indique de montrer les lignes où le motif correspond SANS un crochet de droite]. Etant donné que le modèle de recherche pour exclure un crochet ajoute le crochet au modèle, il ne se correspondra jamais.

Ainsi, vous pouvez écrire une psgrepcommande portable comme suit. Ici, je tiens compte des différences entre Linux, OS X BSD et d’autres. Cela ajoute les en-têtes de colonne de ps, fournit un plus personnalisépsformat qui convient mieux à mes besoins, et affiche les processus listant extra, extra large afin qu’aucun des arguments de la ligne de commande ne manque. Eh bien, la plupart ne sont pas manqués. Java étant Java, il fait souvent les choses de la pire façon possible, de sorte que certains services java fonctionneront au-delà de la longueur maximale autorisée des arguments que la table de processus va suivre. Je crois que c'est 1024 caractères. La longueur autorisée par commande permettant de démarrer un processus est beaucoup plus longue, mais la table des processus du noyau ne prend pas la peine de garder trace de tout ce qui dépasse 1K. Une fois la commande lancée, le nom de la commande et la liste d'arguments ne sont plus nécessaires. Par conséquent, ce qui est stocké dans la table de processus est simplement informatif.

psgrep ()
{
    pattern=[^]]${1};
    case "$(uname -s)" in
        Darwin)
            ps -A -ww -o pid,ppid,nice,pri,pcpu,pmem,etime,user,wchan,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        Linux)
            ps -A -ww -o pid,ppid,tid,nice,pri,pcpu,pmem,etime,user,wchan:20,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        *)  # other UNIX flavors get a minimalist version.
            ps -A -ww | grep -i -e ${pattern}
        ;;
    esac
}
Noah Spurrier
la source
L'inconvénient est que cela correspond en fait à un caractère de plus (devant) que le motif d'origine. Par exemple, cela ne correspondra jamais au PID. Et peut être un peu trompeur lorsqu'il est utilisé avec grep --colour.
Tonin
67

+1 pour la réponse laconique de @jamzed, cependant le PO pourrait avoir besoin d'explications:

ps | grep "[d]jango"

En utilisant cette expression rationnelle, vous lancez un processus auquel sa chaîne ps ne correspondra pas, car l'expression rationnelle correspond "django"et non "[d]jango". De cette façon, vous excluez le processus contenant la chaîne "[d] jango" qui, dans ce cas, est grep; La même chose peut être appliquée à pgrep, egrep, awk, sed, etc ... quelle que soit la commande que vous avez utilisée pour définir l'expression régulière.

De l'homme 7 regex

   A bracket expression is a list of characters enclosed in "[]".  It nor‐
   mally matches any single character from the list (but see  below).   If
   the  list  begins  with  '^',  it matches any single character (but see
   below) not from the rest of the list.  If two characters  in  the  list
   are  separated  by '-', this is shorthand for the full range of charac‐
   ters between those two (inclusive) in the collating sequence, for exam‐
   ple,  "[0-9]" in ASCII matches any decimal digit.  It is illegal(!) for
   two ranges to share an endpoint, for example, "a-c-e".  Ranges are very
   collating-sequence-dependent,  and portable programs should avoid rely‐
   ing on them.
Hmontoliu
la source
2
Cool. En fait, je suis assez à l'aise avec les expressions rationnelles, mais je ne pouvais pas immédiatement penser à un moyen d'éviter que l'expression régulière se corresponde. Il est parfaitement logique de mettre une lettre entre crochets. (Y compris quelque chose comme [^!] Fonctionnerait aussi ...)
Steve Bennett
1
C'est gentil et rusé.
cendres
Pour le cas spécifique "ps", j'utilise "[]" devant le nom du processus que je recherche. Ensuite, je n'ai pas besoin d'analyser le nom du processus spécialement pour l'expression régulière, mais il correspond toujours.
Néromancien
@hmontoliu Il ne fonctionne pas , par exemple: ps aux | grep [s]cript1. Pourriez-vous aider à commenter sur la solution?
mardi
@hmontoliu Ma faute. Il semble que la ligne soit affichée à cause des recherches précédentes ...
SOUser
30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]

coincé
la source
Ajoutez de l'espace si vous avez besoin d'un caractère:ps aux| grep "[Z] "
AD
@jamzed Cela ne fonctionne pas par exemple: ps aux | grep [s]cript1ou ps aux | grep [s]cript2. La ligne grep est toujours affichée. Pourriez-vous aider à commenter sur la solution?
mardi
@jamzed Ma faute. Il semble que la ligne soit affichée à cause des recherches précédentes ...
SOUser
18

Utilisez pgrep à la place: pgrep -lf django

ramruma
la source
Comme d'habitude, j'ai oublié de mentionner la plate-forme (OS X dans ce cas). Vraisemblablement, pgrep fonctionne sur différents linux.
Steve Bennett
Je ne suis pas d'accord, @ramruma. Je suis venu à ce fil précisément parce que pgrepme donne exactement ce problème. Mais je dois dire que je le teste dans CygWin (où psne peut pas afficher la ligne de commande complète du processus).
Sopalajo de Arrierez
Le manuel indique que "le processus pgrep ou pkill en cours d'exécution ne se présentera jamais comme une correspondance.", Et en effet je ne l'ai pas vu le faire.
Deltab
Je viens de faire face à un problème où je pensais que cela pgrepcorrespondait. Il s'avère que cela correspond au nom du bashfichier de script à partir duquel je l'exécutais. L'ajout l'a -xcorrigé, alors il fait une correspondance exacte sur le nom de la commande.
andynormancx
11

Oh, attends, ça marche:

ps | grep django | grep -v grep
Steve Bennett
la source
7
Seulement si la ligne de commande de processus n'inclut pas légitimement grep, vous ne pouvez pas compter sur dans le cas général.
un CVn
8

ps -d | grep django

de l'homme ps:

 -d                  Lists information  about  all  processes
                     except session leaders.
blabla
la source
montre toujours grep sur le mien ...
Kevin
Oui, cela fonctionne pour moi sur OS X.
Steve Bennett
Ne fonctionne pas si bien sur Linux.
Acumenus
Plus généralement, les options pssont notoirement non-portables, donc sans information sur la plate-forme à laquelle cela est destiné, cette réponse n'est pas très utile. De plus, cela n’est évidemment pas suffisant lorsque vous n'êtes pas sûr que le processus que vous recherchez n’est pas un leader de processus (c’est-à-dire que cela peut vous aider si votre cible est un démon, mais généralement pas autrement).
tripleee
Drôle, sur Mac, cela ne montre que le processus grep et filtre tout le reste.
Christopher Hunter