Почему эта подстановка команд ожидает завершения фонового задания?

Я пытаюсь получить PID фонового задания с подстановкой команд. Фоновая работа начинается с setsid, Проблема в том, что родительский процесс поражен подстановкой команд.

Вот пример сценария:

#!/bin/bash

if [ "$1" = "start" ]; then
    while true; do date > "bg.date"; sleep 1; done &
    echo $!
    exit 0
fi

pid="$(setsid "$0" start)"
echo "pid=$pid"
  • ./script start работает как положено (то есть сразу выходит из командной строки bash, пока выполняется фоновое задание).
  • setsid ./script start также работает как ожидалось.
  • Но ./script не работает должным образом: он не печатает PID (если фоновое задание не уничтожено вручную).

1 ответ

Решение

Подстановка команд осуществляется через каналы. Конец чтения ждет закрытия всех авторов, но вы оставляете конец записи открытым бесконечно долго, как стандартный вывод вашего бесконечного цикла.

Вы можете перенаправить цикл, чтобы избежать этого:

#!/bin/bash

if [ "$1" = "start" ]; then
    while true; do date > "bg.date"; sleep 1; done > /dev/null &
    echo $!
    exit 0
fi

pid="$(setsid "$0" start)"
echo "pid=$pid"

Если повторно входящий setsid Это была попытка заставить скрипт не зависать, вам будет приятно узнать, что это не нужно, и вы можете переписать его более надежно с помощью простой функции.

Другие вопросы по тегам