Ссылки на рабочие места 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 ) &