Ссылки на рабочие места Bash на другие рабочие места

Я хочу сослаться на фоновую работу Bash в другой фоновой работе Bash. Это возможно?

Например, скажем, я начинаю фоновую работу:

$ long_running_process &
[1] 12345

Теперь я хочу, чтобы что-то случилось, когда эта работа закончится, поэтому я могу использовать wait:

$ wait %1 && thing_to_happen_after_long_running_process_finishes

Тем не менее, это заблокирует, и я хочу, чтобы мой терминал снова делал другие вещи, но Ctrl+Z ничего не делает.

Попытка начать это в фоновом режиме, в первую очередь, проваливается:

$ { wait %1 && thing_to_happen_after_long_running_process_finishes; } &
[2] 12346
-bash: line 3: wait: %1: no such job
$ jobs
[1]-  Running     long_running_process &
[2]+  Exit 127    { wait %1 && thing_to_happen_after_long_running process_finishes; }

Есть ли какой-либо способ ссылаться на одну работу, используя wait в другой фоновой работе?

Я вижу это поведение, используя GNU Bash 4.1.2(1)-релиз.

2 ответа

Решение

Оболочка может только wait на своих детей. Поскольку фоновое задание создает новую оболочку, wait в этой оболочке можно ожидать только своих собственных потомков, а не потомков своего родителя (т. е. оболочки, из которой разветвлено background-wait). Для того, что вы хотите, вам нужно планировать заранее:

long_running_process && thing_to_happen_after &

Есть одна альтернатива:

long_running_process &
LRP_PID=$!

{ while kill -0 $LRP_PID 2> /dev/null; do sleep 1; done; thing_to_happen_after; } &

Это создаст цикл, который будет пытаться пропинговать ваш фоновый процесс раз в секунду. Когда процесс завершен, kill потерпит неудачу и перейдет к программе постобработки. Это несет небольшой риск того, что ваш процесс завершится, и другой процесс получит такой же идентификатор процесса между проверками, и в этом случае kill может запутаться и подумать, что ваш процесс все еще работает, хотя на самом деле это новый. Но это очень небольшой риск, и на самом деле это может быть хорошо, если thing_to_happen_after задерживается немного дольше, пока не происходит процесс с идентификатором $LRP_PID,

Попробуйте что-то вроде этого:

  x2=$(long_running_process && thing_to_happen_after_long_running_process_finishes ) &
Другие вопросы по тегам