El PID de un proceso secundario en segundo plano se almacena en $!
, y el proceso actual es $$
:
fpfunction &
child_pid=$! # in parent process, child's pid is $!
parent_pid=$$ # in parent process, parent's pid is $$
Cuando está en la función en segundo plano, el PID de los procesos secundarios es $BASHPID
en lugar de $$
, que ahora es el PID principal:
fpfunction() {
local child_pid=$BASHPID # in child process, child's pid is $BASHPID
local parent_pid=$$ # in child process, parent's pid is $$
...
}
También por lo que vale, puede combinar las instrucciones de bucle en un solo bucle for tipo C:
for ((n = 1; n < 20; ++n)); do
echo "Hello World-- $n times"
sleep 2
echo "Hello World2-- $n times"
done
Del manual de Bash:
!
Se expande al ID de proceso del comando en segundo plano (asincrónico) ejecutado más recientemente.
es decir, use $!
.
Los PID del script, hijo y padre siempre se pueden determinar correctamente en el script padre, independientemente del método empleado para iniciarlo:
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
Si la información es accesible en el proceso secundario depende de cómo se haya iniciado el proceso secundario.
Con la función:
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
}
y las llamadas asíncronas:
child FUNC "${indx}" "${$}" &
( child SUB "${indx}" "${$}" ) &
sh -c "${FUNCTIONS}
child SH "${indx}" \"${$}\"" &
el resultado muestra que solo la función invocada con un sh -c
explícito tiene acceso a la información PID/PPID correcta:
# --------------------------------------------------
# :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
El script de prueba completo es:
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