Bash запустить группу из двух детей в фоновом режиме и убить их позже - PullRequest
0 голосов
/ 13 апреля 2020

Давайте сгруппируем две команды (cd и bash ..) вместе следующим образом:

#!/bin/bash

C="directory"
SH="bash process.sh"

(cd ${C}; ${SH})&
PID=$!
sleep 1
KILL=`kill ${PID}`

process.sh выводит дату (каждую секунду и пять раз):

C=0
while true
do
    date
    sleep 1
    if [ ${C} -eq 4 ]; then
        break
    fi
    C=$((C+1))
done

Теперь я действительно ожидал бы, что фоновый подпроцесс будет убит сразу после 1 секунды, но он просто продолжается, как будто ничего не происходит. INB4: «Почему бы вам просто не bash directory/process.sh» Нет, этот cd является лишь примером. Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 13 апреля 2020

Используйте exec, когда вы хотите, чтобы процесс заменил себя на месте, вместо создания нового подпроцесса с собственным PID.

То есть этот код может создать two подпроцессов, сохраняя PID первого в $!, но затем используя второй для выполнения process.sh:

# store the subshell that runs cd in $!; not necessarily the shell that runs process.sh
# ...as the shell that runs cd is allowed to fork off a child and run process.sh there.
(cd "$dir" && bash process.sh) & pid=$!

... тогда как этот код создает только один подпроцесс, потому что он использует exec, чтобы первый процесс заменил себя вторым:

# explicitly replace the shell that runs cd with the one that runs process.sh
# so $! is guaranteed to have the right thing
(cd "$dir" && exec bash process.sh) &
0 голосов
/ 14 апреля 2020

вы можете проверить все дочерние процессы с помощью "ps --ppid $$", так что

#!/bin/bash

C="directory"
SH="bash process.sh"

(cd ${C}; ${SH})&
PID=$!
sleep 1
ps -o pid= --ppid $$|xargs kill
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...