GNU/Linux >> Belajar Linux >  >> Linux

Cara mendapatkan PID dari proses anak bercabang di skrip Shell

PID dari proses anak latar belakang disimpan di $! , dan proses saat ini adalah $$ :

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

Saat berada di fungsi latar belakang, PID proses anak adalah $BASHPID bukan $$ , yang sekarang menjadi PID induk:

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

Juga untuk apa nilainya, Anda dapat menggabungkan pernyataan perulangan menjadi satu perulangan for seperti C:

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

Dari manual Bash:

!

Memperluas ke ID proses dari perintah latar belakang (asinkron) yang terakhir dieksekusi.

yaitu, gunakan $! .


Skrip, PID anak dan induk selalu dapat ditentukan dengan benar dalam skrip induk terlepas dari metode yang digunakan untuk memulainya:

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

Apakah informasi dapat diakses dalam proses anak bergantung pada bagaimana proses anak dimulai.

Dengan fungsi:

 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
 }

dan panggilan asinkron:

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

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

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

output menunjukkan, bahwa hanya fungsi yang dipanggil dengan sh -c eksplisit memiliki akses ke informasi PID/PPID yang benar:

# --------------------------------------------------
#   :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

Skrip pengujian lengkapnya adalah:

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. Bagaimana Cara Mendapatkan Alamat Ip Eksternal Dalam Script Shell?

  2. Bagaimana Cara Mendapatkan Alamat Ip Sendiri Dan Menyimpannya Ke Variabel Dalam Script Shell?

  3. Bagaimana cara menghitung penggunaan CPU dari suatu proses oleh PID di Linux dari C?

  1. Bagaimana cara mendapatkan ID proses dari proses latar belakang?

  2. Bagaimana cara mendapatkan ID proses untuk mematikan proses nohup?

  3. Bagaimana cara mendapatkan PID dengan nama proses?

  1. Bagaimana saya bisa mendapatkan alamat IP eksternal saya dalam skrip shell?

  2. Bagaimana cara mendapatkan pid dari suatu proses dan mengaktifkan kill -9 di skrip Shell?

  3. Cara mendapatkan pid dari proses yang baru saja dimulai