Использование уничтожения PID может быть ненадежным, если tail -f
завершается слишком рано (например, файл не существует).
Еще одно более общее решение, которое также остановит «таймер уничтожения», если оно будет выполнено до истечения времени ожидания, - это использовать wait
и kill %%
( %%
указывает на самое последнее задание, запущенное bash - с использованием и
).
Конструкция будет выглядеть так (в которой sleep 2
- любая пользовательская команда с параметрами и т. Д., А таймаут установлен на 10 секунд):
# Your command that may take some (or not) time to execute:
sleep 2 &
# Set a timer that kills the last started job
sleep 10 & wait -n 1; kill %%; wait -n 1
Эта конструкция будет ждать, пока не будет достигнут тайм-аут , или пользовательская команда завершена (в этом случае sleep 2
всегда останавливается первым). Тогда, соответственно, команда или тайм-аут будут уничтожены с помощью kill %%
. Затем последний wait -n 1
блокирует дальнейшее выполнение до тех пор, пока команда или тайм-аут не будут фактически уничтожены (это необязательно, но, вероятно, желательно).
Примечание. Более ранние команды, выполняемые параллельно, не будут затронуты, как это требуется и ожидается.
Более практичный пример с чтением строки из именованного канала с тайм-аутом, но для которого нельзя использовать флаг тайм-аута read
:
# Custom bash function to set timeout in seconds for the most recently started job (parallel execution).
timeout() { sleep $1 & wait -n 1; kill %%; wait -n 1 }
# Example 1:
mkfifo /tmp/test
read ln </tmp/test &
timeout 10
Потому что в него ничего не записано / tmp / test
время ожидания истечет через 10 секунд. Чтобы показать, что даже когда команда завершается немедленно, она останавливает таймер уничтожения:
# Example 2:
mkfifo /tmp/test
echo "Hello" >/tmp/test &
ln="$(read ln </tmp/test && echo -e "$ln" & timeout 10)"
echo "Line was read: $ln"
Примечание относительно практического использования именованного канала.Поскольку read ln
выполняется в подоболочке, к нему нельзя получить доступ в (родительском) скрипте. Поэтому в строке печатается echo
, чтобы сохранить ее в (другой) переменной ln
.