bash запускает дополнительные ложные фоновые процессы - PullRequest
1 голос
/ 06 февраля 2012

Я вижу очень, очень странное поведение с bash (версия 3.2.25 на RHEL 5.3).

У меня есть скрипт «Launcher», который выполняет следующие действия (в качестве процесса переднего плана, работающего в терминале, который остается открытым):

  1. Запускает программу A в фоновом режиме и завершает работу.
  2. A затем запускает два (процесса) экземпляра программы B в фоновом режиме (скажем, B1, B2);
  3. A, также запускает один экземпляр программы C в фоновом режиме.

Идея, приведенная выше, по существу состоит в том, чтобы А, С и два В общались друг с другом, пока пользователь не убьет их. (Они продолжают работать с while sleep DURATION; do ... ; done петлей.)

Проблема:

После того, как вышеуказанные 3 шага выполнены, когда я многократно выдаю ps -ef из другого окна терминала, я иногда вижу несколько дополнительных, ложных экземпляров B (скажем, B3, B4 ...) и / или иногда дополнительный, ложный случай внесения в список А!

Эти дополнительные экземпляры временны - они приходят и уходят из списка ps -ef.

Кроме того, эти ложные случаи оказываются детьми, а не братьями и сестрами, действительных (или желаемых) процессов. Например, B3 и B4 будут указывать B1 и B2 соответственно в качестве своих родителей; аналогично, ложный A2 перечислит A как своего родителя!

Теперь я ДОВОЛЬНО ЗАРАБОТАННЫЙ УВЕРЕН , что я НЕТ ПУТИ создаю любые дополнительные экземпляры B изнутри B или любой экземпляр A изнутри A.

Итак, что здесь происходит?

Большое спасибо, заранее.

PS: Я видел похожую проблему (из нескольких ложных случаев) некоторое время назад в контексте заданий cron, которые были предназначены для бесконечного зависания при их первом первом запуске. Здесь также я видел бы несколько экземпляров моей работы cron, хотя у меня была явная логика для предотвращения запуска дополнительных экземпляров crond (путем проверки наличия файла блокировки на диске). И даже здесь я не мог понять проблему.


$ ps -ejfH 
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     16143 28525 28474 11126  0 23:14 pts/1    00:00:00       [B] <defunct>
root     16144 28525 28474 11126  0 23:14 pts/1    00:00:00       /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C

$ ps -ejfH 
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C
root     18579 28503 28474 11126  0 23:14 pts/1    00:00:00     /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     22717 28525 28474 11126  0 23:14 pts/1    00:00:00       /bin/bash B 
root     22718 22717 28474 11126  0 23:14 pts/1    00:00:00         /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     32021 28531 28474 11126  0 23:15 pts/1    00:00:00       /bin/bash B 
root     32023 32021 28474 11126  0 23:15 pts/1    00:00:00         [B] <defunct>
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C
root     32013 28503 28474 11126  0 23:15 pts/1    00:00:00     /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C
root      2310 28503 28474 11126  0 23:15 pts/1    00:00:00     /bin/bash A
root      2324  2310 28474 11126  0 23:15 pts/1    00:00:00       /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root      9219 28531 28474 11126  0 23:16 pts/1    00:00:00       [B] <defunct>
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:02     /bin/bash C

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:02     /bin/bash C
root      9692 28503 28474 11126  0 23:16 pts/1    00:00:00     /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:33   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:02     /bin/bash C
root     15686 28503 28474 11126  0 23:16 pts/1    00:00:00     /bin/bash A

1 Ответ

5 голосов
/ 06 февраля 2012

Существует ряд функций bash, которые порождают подоболочку для выполнения части скрипта.Я предполагаю, что ваши сценарии A и B используют некоторые из этих функций.Помимо явного создания подоболочки путем включения команд в ( ... ), подоболочки будут также создаваться для любых команд bash, выполняемых в конвейере, в подстановке команд ($( ... ) или обратные метки) или в фоновом режиме с &.Вот скрипт, который иллюстрирует это:

$ cat a
#!/bin/bash

echo "Initial subshell count: $BASH_SUBSHELL"
ps -opid,ppid,command | egrep "PID|bash ./a"

echo "input" | while read line; do
    echo "Subshell count in pipeline: $BASH_SUBSHELL"
    ps -opid,ppid,command | egrep "PID|bash ./a"
done

output=$(echo "Subshell count in \$(): $BASH_SUBSHELL"
   ps -opid,ppid,command | egrep "PID|bash ./a"
)
echo "$output"

(   echo "Subshell count in (): $BASH_SUBSHELL"
    ps -opid,ppid,command | egrep "PID|bash ./a"
)

{   echo "Subshell count in backgrounded command: $BASH_SUBSHELL"
    ps -opid,ppid,command | egrep "PID|bash ./a"
} &
sleep 1
$ ./a
Initial subshell count: 0
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1412  1410 egrep PID|bash ./a
Subshell count in pipeline: 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1414  1410 /bin/bash ./a
 1416  1414 egrep PID|bash ./a
Subshell count in $(): 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1417  1410 /bin/bash ./a
 1419  1417 egrep PID|bash ./a
Subshell count in (): 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1420  1410 /bin/bash ./a
 1422  1420 egrep PID|bash ./a
Subshell count in backgrounded command: 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1423  1410 /bin/bash ./a
 1426  1423 egrep PID|bash ./a

(Примечание: в примере echo ... | while ... и echo, и цикл while выполняются в подоболочках; но команда echo завершается слишком быстро, чтобы psпокажи.)

...