Запустите процесс из Bash-скрипта в фоновом режиме, затем перенесите его на передний план - PullRequest
2 голосов
/ 14 мая 2019

Ниже приведена упрощенная версия кода, который у меня есть:

#!/bin/bash

myfile=file.txt
interactive_command > $myfile &
pid=$!

# Use tail to wait for the file to be populated
while read -r line; do
  first_output_line=$line
  break # we only need the first line
done < <(tail -f $file)
rm $file

# do stuff with $first_output_line and $pid
# ...
# bring `interactive_command` to foreground?

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

Однако, похоже, что использование fg %1 не работает в контексте скрипта, и я не могу использовать fg с PID. Есть ли способ, которым я могу это сделать?

(Кроме того, есть ли более элегантный способ захвата первой строки вывода без записи во временный файл?)

1 Ответ

1 голос
/ 14 мая 2019

Управление заданиями с использованием fg и bg доступно только для интерактивных оболочек (т. Е. При наборе команд в терминале).Обычно сценарии оболочки выполняются в неинтерактивных оболочках (по той же причине, по которой псевдонимы не работают в сценариях оболочки по умолчанию)

Поскольку PID уже хранится в переменной, приоритетный процесс аналогичен ожиданию наэто (см. Job Control Builtins ).Например, вы можете просто сделать

wait "$pid"

Также у вас есть базовая версия coproc bash встроенная , которая позволяет получать стандартные выходные сообщения, полученные из фоновых команд.Он предоставляет два файловых дескриптора, хранящихся в массиве, с помощью которых можно читать выходные данные из stdout или вводить входные данные в его стандартный

coproc fdPair interactive_command 

Синтаксис обычно coproc <array-name> <cmd-to-bckgd>.Массив заполняется встроенными идентификаторами файловых дескрипторов.Если переменная не используется явно, она заполняется в переменной COPROC.Таким образом, ваше требование может быть записано как

coproc fdPair interactive_command 
IFS= read -r -u "${fdPair[0]}" firstLine
printf '%s\n' "$firstLine"
...