See also linux - How to get PID from forked child process in shell script - Stack Overflow.
The script, child and parent PIDs can always be determined correctly in the parent script independent of the method employed to start it:
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
Whether the information is accesible in the child process depends on how the child process has been started.
With the function:
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
}
and the asynchrounous calls:
child FUNC "${indx}" "${$}" &
( child SUB "${indx}" "${$}" ) &
sh -c "${FUNCTIONS}
child SH "${indx}" \"${$}\"" &
the output shows, that only the function invoked with an explicit sh
-c
has access to the correct PID/PPID information:
# --------------------------------------------------
# :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
The complete test script is:
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