bash - PID für ein Skript mit dem Skriptdateinamen abrufen

10

Ich habe zwei Skripte:

  • running_script
  • script_one

Ich muss die PID für die / alle Instanzen running_scriptabrufen, die unter einem Benutzernamen ausgeführt werden, und dann pkilldie running_scriptProzesse und Tochter stoppen .

Wir haben so etwas erwartet wie:

ps -fu will | grep running_script

um den / die running_scriptProzess (e) zu finden. Wenn Sie jedoch die PID mit der Ausgabe des ps-Befehls vergleichen, wird der Befehl cmd wie folgt angezeigt : "bin / bash" für den running_scriptProzess.

running_scriptwird als getrennter Prozess ( &Operator) ausgeführt, der gestartet wird script_one. Ich drucke die PIDs zu Beginn aus, um sie mit psder Ausgabe des Befehls zu vergleichen .

running_script  &
echo $! -- $BASHPID

Im realen Anwendungsfall werden für einige running_scriptProzesse keine PIDs ausgeführt. Auch script_onekann oder auch nicht ein abgetrenntes Verfahren aus dem seinem running_scriptElternteil.

Für die Zwecke der Übung werden script_onenur Schleifen ausgeführt.

while [ true ]
do
    echo "  $0 - 35sec ..."
    sleep 35
done

Dies ist jedoch nur das Beispiel. Die Anforderung besteht darin, die PID für die übergeordneten running_scriptProzesse zu erhalten.

Gibt es eine Option psoder einen anderen Befehl, der mir den Namen der Skriptdatei und die PID geben kann? Oder eine Methode, um einen Namen festzulegen , nach dem gesucht werden kann?

Im letzten Anwendungsfall kann es mehrere Fälle geben running_script, in denen die Auswahl nach Namen die bisher beste Option ist.

Beispiel

Ich dachte, es könnte hilfreich sein, zu zeigen, was der psBefehl anzeigt, da die meisten Antworten zu glauben scheinen, dass dies funktionieren wird. Ich habe dieses Beispiel erst vor einiger Zeit ausgeführt.

$  ./running_script &
$  echo $! - $BASHPID
9047 - 3261
$  ps -ef | grep will

  UID     PID  PPID  C STIME TTY          TIME CMD
  will   8862  2823  0 22:48 ?        00:00:01 gnome-terminal
  will   8868  8862  0 22:48 ?        00:00:00 gnome-pty-helper
  will   8869  8862  0 22:48 pts/4    00:00:00 bash
* will   9047  3261  0 22:55 pts/2    00:00:00 /bin/bash
  will   9049  9047  0 22:55 pts/2    00:00:00 /bin/bash
  will   9059  2886  0 22:56 pts/0    00:00:00 man pgrep
  will   9070  9059  0 22:56 pts/0    00:00:00 pager -s
  will  10228  9049  0 23:31 pts/2    00:00:00 sleep 35
  will  10232  8869  0 23:31 pts/4    00:00:00 ps -ef
  will  10233  8869  0 23:31 pts/4    00:00:00 grep --colour=auto william

Ich habe PID # 9047 markiert, zeigt einfach: - will 9047 3261 0 22:55 pts / 2 00:00:00 / bin / bash

Gibt es so etwas wie ein " Jobname " -Attribut, das ich unter Linux festlegen könnte?

werden
quelle
Wäre es ausreichend, die PID des übergeordneten Prozesses von zu erhalten script1?
Terdon
Um Zeit zu sparen, zeigt jede ps-Option "bash / bash" und NICHT "running_script" an, wenn sie running_scriptüber die Befehlszeile / das Terminal angezeigt wird.
wird
Ich teste diese mit v4.3.11 (1) -release unter Linux Mint 17. Voraussetzung ist die PID von running_script. Es gibt einen (guten) Compliance-Grund für diese Anforderung, der sich aus den bereits laufenden Hardware- und Softwaresystemen ergibt.
wird
ps --version-> "procps-ng version 3.3.9"
wird

Antworten:

14

Versuchen Sie es pgrep -f running_script- die Option -f verwendet die gesamte Befehlszeile, um eine Übereinstimmung herzustellen, nicht nur den Prozessnamen

Glenn Jackman
quelle
Das Ergebnis ist eine Null (oder keine Ausgabe). Das ist auf Gnu Bash: v4.3.11 (1) -Veröffentlichung
wird
1
Fügen Sie -l( --list-name) zu pgrep hinzu, um diese Prozesse zu benennen. Zum Beispiel für die Ausführung von Skripts claws2postgres.sh, pgrep -l -f claws2postgreskehrt 23538 claws2postgres..
Victoria Stuart
4

ps -o pid,args -C bash | awk '/running_script/ { print $1 }'

Dies verwendet ps, um die PID und die Argumente für alle Bash-Prozesse abzurufen, und verwendet dann awk, um die PID (Feld 1) des Übereinstimmungsprozesses zu drucken.

Übrigens, ps -o pid,args -C bashgibt Ihnen die PID und den Namen der Skriptdatei an, nach der Sie gefragt haben - der Name des Skripts steht in den Argumenten des bashBefehls.

Wenn Sie pseher pgrepdie vollen Fähigkeiten als das außerordentlich hässliche ps ... | grep -v grep | grep | awkKonstrukt nutzen wollen, anstatt es zumindest zu nutzen . Der letzte grepwird nicht einmal benötigt, da awker die Musterübereinstimmung durchführen kann. Tatsächlich wird keiner der Greps benötigt, da awk alles kann:ps ax | awk '! /awk/ && /myprocessname/ { print $1}'

cas
quelle
Das Ergebnis ist eine Null (oder keine Ausgabe), gnu bash: v4.3.11 (1) -release. Die Ausgabe des Befehls ps lautet: 9047 / bin / bash 9049 / bin / bash, 8869 bash. Ich nehme an, PID 8869 ist der Bash-Prozess der Eltern (Mutter aller). Möglicherweise gibt es ein anderes Ergebnis, wenn der running_scriptBefehl von einem Skript oder etwas (??) anstatt vom Terminal (Shell) ausgeführt wird.
wird
Von welcher Version pslaufen Sie? Versuchen Sie es ps --version. Beide ps -efund ps -o argssollen die vollständige Befehlszeile einschließlich der Argumente anzeigen. Und haben Sie eine der Umgebungsvariablen, die gegen Ende des man psSatzes erwähnt werden?
Cas
Ich habe die Version in die Frage gestellt: "procps-ng version 3.3.9". Der Münzsystemmonitor zeigt die gleichen Informationen an. Es verwendet wahrscheinlich ps (auch sowieso). Das Prozesspseudogerät zeigt jedoch nur Bash / Bash an - was mich glauben lässt, dass es sich um Bash handelt, das die Befehlsinformationen setzt.
wird
Ja, du hast recht. bashändert seine Argumente in ps. Ich werde versuchen herauszufinden, ob es eine Möglichkeit gibt ps, die wahren Argumente zu zeigen. In der Zwischenzeit könnten Sie so etwas versuchen, wenn Sie unter Linux laufenps h -o pid -C bash | xargs -IXX grep -sEl 'running_script' /proc/XX/cmdline | sed -re 's:/proc/([^/]*)/.*:\1:'
cas
Zu Ihrer Information, bashändert seinen Namen nur, pswenn Sie das Skript als ausführen bash scriptname.sh. Wenn Sie es nur ./scriptname.sh(oder /path/to/scriptname.sh) ausführen, wird der tatsächliche Name des Skripts inps
cas
1
ps - ef | grep -v grep | grep <script_name> | awk '{print $2}'

Der obige Befehl gibt die PID für den Skriptnamen an. Sie können das Skript auch eine temporäre Datei mit der laufenden PID schreiben lassen.

Fügen Sie eine Zeile in das Skript ein: echo $$>/tmp/script_pid.tmp

Obi Wan Kenobi
quelle
0
#!/bin/bash

# pidofargs.sh
# get process id by first argument of a process
# using `ps -eo pid,args` and `read -a`

# sample use: pidofargs.sh python /usr/bin/youtube-dl

search_grep="$1" # first filter
search_arg1="$2" # second filter

# first filter
ps -eo pid,args | grep "$search_grep" | while read pid args
do
  read -a arg < <(echo "$args")

  # pid    = process id
  # arg[0] = executable file of process
  # arg[1] = first argument of process

  # second filter
  if [[ "${arg[1]}" == "$search_arg1" ]]
  then
    # success
    echo $pid
    break
  fi

done
Mila Nautikus
quelle