GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So erhalten Sie die PID von einem gegabelten untergeordneten Prozess im Shell-Skript

Die PID eines untergeordneten Prozesses im Hintergrund wird in $! gespeichert , und der aktuelle Prozess ist $$ :

fpfunction &
child_pid=$!     # in parent process, child's pid is $!
parent_pid=$$    # in parent process, parent's pid is $$

In der Funktion im Hintergrund ist die PID der untergeordneten Prozesse $BASHPID statt $$ , die jetzt die übergeordnete PID ist:

fpfunction() {
    local child_pid=$BASHPID   # in child process, child's pid is $BASHPID
    local parent_pid=$$        # in child process, parent's pid is $$
    ...
}

Auch für das, was es wert ist, können Sie die Schleifenanweisungen in einer einzigen C-ähnlichen for-Schleife kombinieren:

for ((n = 1; n < 20; ++n)); do
    echo "Hello World-- $n times"
    sleep 2
    echo "Hello World2-- $n times"
done

Aus dem Bash-Handbuch:

!

Erweitert auf die Prozess-ID des zuletzt ausgeführten (asynchronen) Hintergrundbefehls.

d.h. verwenden Sie $! .


Die Script-, Child- und Parent-PIDs können im Parent-Script immer korrekt ermittelt werden, unabhängig davon, mit welcher Methode es gestartet wird:

child () { :; }

child &
( child ) &
sh -c "child () { :; }; child" &

script_pid="${$}"    # PID of the running shell script
child_pid="${!}"     # last started child process
parent_pid="${PPID}" # PID of parent process

Ob die Informationen im untergeordneten Prozess zugänglich sind, hängt davon ab, wie der untergeordnete Prozess gestartet wurde.

Mit der Funktion:

 child ()
 {
     sleep "$( expr "${2-1}" '*' 5 )"
     script_pid="${3-}"
     child_pid="${$}"
     parent_pid="${PPID}"
     message="CHILD ${1-}"
     test x"${script_pid}" != x"${child_pid}" || message="${message}"' UNFORTUNATELY WRONG!'
     report
     sleep 20
 }

und die asynchronen Aufrufe:

child FUNC "${indx}" "${$}" &

( child SUB "${indx}" "${$}" ) &

sh -c "${FUNCTIONS}
child SH "${indx}" \"${$}\"" &

die Ausgabe zeigt, dass nur die Funktion mit einem expliziten sh -c aufgerufen wird Zugriff auf die richtigen PID/PPID-Informationen hat:

# --------------------------------------------------
#   :PRC:   CHILD FUNC UNFORTUNATELY WRONG!
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20634]
#   :DBG:   parent_pid     : [10857]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 10857 10853  20   0 2756840 1942820 poll_s Ssl ?       95:15 emacs
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh

# --------------------------------------------------
#   :PRC:   CHILD SUB UNFORTUNATELY WRONG!
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20634]
#   :DBG:   parent_pid     : [10857]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 10857 10853  20   0 2756840 1942820 poll_s Ssl ?       95:15 emacs
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh

# --------------------------------------------------
#   :PRC:   CHILD SH
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20658]
#   :DBG:   parent_pid     : [20634]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh
0  1114 20658 20634  20   0   4636  1720 wait   S+   pts/22     0:00 sh -c show_processes () {     test -z

Das vollständige Testskript lautet:

FUNCTIONS="$(
cat <<'EOF'
show_processes ()
{
    test -z "${1-}" || printf "%s\n" "${1}"

    _sep=
    pids_rx=
    for _pid in "${script_pid}" "${child_pid}" "${parent_pid}"
    do
    test -n "${_pid}" || continue
    pids_rx="${pids_rx}${_sep}${_pid}"
    _sep='\|'
    done

    ps axl | head -1
    ps axl | grep '^[^ ]*  *[^ ]*  *\('"${pids_rx}"'\)' | cut -c -107 | sort -k 3
}

report ()
{
    printf "%s\n" ""
    printf >&2 "# --------------------------------------------------\n"
    printf >&2 "#   "":PRC:   %s\n" "${message}"
    test -z "${script_pid}" || \
    printf >&2 "#   "":DBG:   %-${dbg_fwid-15}s: [%s]\n" "script_pid" "${script_pid}"
    test -z "${child_pid}" || \
    printf >&2 "#   "":DBG:   %-${dbg_fwid-15}s: [%s]\n" "child_pid" "${child_pid}"
    test -z "${parent_pid}" || \
    printf >&2 "#   "":DBG:   %-${dbg_fwid-15}s: [%s]\n" "parent_pid" "${parent_pid}"
    show_processes
}

child ()
{
    sleep "$( expr "${2-1}" '*' 5 )"
    script_pid="${3-}"
    child_pid="${$}"
    parent_pid="${PPID}"
    message="CHILD ${1-}"
    test x"${script_pid}" != x"${child_pid}" || message="${message}"' UNFORTUNATELY WRONG!'
    report
    sleep 20
}
EOF
)"

eval "${FUNCTIONS}"

shell_report ()
{
    script_pid="${$}"
    child_pid="${!}"
    parent_pid="${PPID}"
    sleep 1
    message="SHELL ${indx}"
    report
    indx="$( expr "${indx}" + 1 )"
}

indx=1

child FUNC "${indx}" "${$}" &
shell_report

( child SUB "${indx}" "${$}" ) &
shell_report

sh -c "${FUNCTIONS}
child SH "${indx}" \"${$}\"" &
shell_report

sleep "$( expr "${indx}" '*' 5 )"
The complete output is:

# --------------------------------------------------
#   :PRC:   SHELL 1
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20636]
#   :DBG:   parent_pid     : [10857]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 10857 10853  20   0 2756840 1942820 poll_s Ssl ?       95:15 emacs
0  1114 20634 10857  20   0   4636  1728 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh
1  1114 20636 20634  20   0   4636   104 wait   S+   pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh

# --------------------------------------------------
#   :PRC:   SHELL 2
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20647]
#   :DBG:   parent_pid     : [10857]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 10857 10853  20   0 2756840 1942820 -   Rsl  ?         95:15 emacs
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh
1  1114 20647 20634  20   0   4636   108 wait   S+   pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh

# --------------------------------------------------
#   :PRC:   SHELL 3
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20658]
#   :DBG:   parent_pid     : [10857]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 10857 10853  20   0 2756840 1942820 poll_s Ssl ?       95:15 emacs
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh
0  1114 20658 20634  20   0   4636   928 wait   S+   pts/22     0:00 sh -c show_processes () {     test -z

# --------------------------------------------------
#   :PRC:   CHILD FUNC UNFORTUNATELY WRONG!
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20634]
#   :DBG:   parent_pid     : [10857]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 10857 10853  20   0 2756840 1942820 poll_s Ssl ?       95:15 emacs
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh

# --------------------------------------------------
#   :PRC:   CHILD SUB UNFORTUNATELY WRONG!
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20634]
#   :DBG:   parent_pid     : [10857]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 10857 10853  20   0 2756840 1942820 poll_s Ssl ?       95:15 emacs
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh

# --------------------------------------------------
#   :PRC:   CHILD SH
#   :DBG:   script_pid     : [20634]
#   :DBG:   child_pid      : [20658]
#   :DBG:   parent_pid     : [20634]
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1114 20634 10857  20   0   4636  1732 wait   Ss+  pts/22     0:00 sh /tmp/check_child_and_parent_pids.sh
0  1114 20658 20634  20   0   4636  1720 wait   S+   pts/22     0:00 sh -c show_processes () {     test -z

Linux
  1. Wie kann ich Dateien aus einem UNIX-Shell-Skript per FTP übertragen und herunterladen?

  2. Wie erhalte ich einen Rückgabewert von CHILD PROCESS?

  3. Abrufen der PID des Prozesses im Shell-Skript

  4. So erhalten Sie einen untergeordneten Prozess aus einem übergeordneten Prozess

  5. Wie beendet man den Prozess von Python mit PID?

So finden Sie den Prozessnamen anhand seiner PID

Wie führe ich einen Befehl in einem Shell-Skript aus?

Wie bekomme ich PID nach Prozessname?

Wie erhalte ich die übergeordnete PID eines bestimmten Prozesses in GNU/Linux von der Befehlszeile aus?

Wie erhalte ich die PID eines Prozesses und rufe im Shell-Skript kill -9 darauf auf?

Wie man einen gerade gestarteten Prozess pipi bekommt