Подтвердить что ты не робот

Как получить идентификатор процесса и код выхода из bash script?

Мне нужен bash script, который выполняет следующие действия:

  • Запускает фоновый процесс со всем выходом, направленным на файл
  • Записывает код выхода процесса в файл
  • Возвращает процесс pid (сразу, а не когда процесс завершается).
  • script должен выйти из

Я могу получить pid, но не код выхода:

$ executable >>$log 2>&1 &
pid=`jobs -p`

Или, я могу записать код выхода, но не pid:

$ executable >>$log;
# blocked on previous line until process exits
echo $0 >>$log;

Как я могу сделать все это одновременно?

4b9b3361

Ответ 1

pid находится в $!, нет необходимости запускать jobs. Возвращаемый статус возвращается wait:

$executable >> $log 2>&1 &
pid=$!
wait $!
echo $?  # return status of $executable

РЕДАКТИРОВАТЬ 1

Если я понимаю дополнительное требование, указанное в комментарии, и вы хотите, чтобы script немедленно возвращался (не дожидаясь завершения команды), тогда не будет возможно, чтобы начальный script записывал статус выхода команды. Но достаточно просто, чтобы посредник записывал статус выхода, как только ребенок заканчивается. Что-то вроде:

sh -c "$executable"' & echo pid=$! > pidfile; wait $!; echo $? > exit-status' &

должен работать.

РЕДАКТИРОВАТЬ 2

Как указано в комментариях, это решение имеет условие гонки: главный script заканчивается перед написанием pidfile. ОП решает это, выполняя опрос петли сна, что является мерзостью, и я боюсь, что ночью у меня будут проблемы со сном, зная, что я, возможно, мотивировал такую ​​пародию. ИМО, правильная вещь - подождать, пока ребенок не будет сделан. Поскольку это неприемлемо, вот решение, которое блокирует чтение до того, как файл pid существует, а не выполняет цикл:

{ sh -c "$executable > $log 2>&1 &"'
echo $! > pidfile
echo   # Alert parent that the pidfile has been written
wait $!
echo $? > exit-status
' & } | read