У меня есть сценарий оболочки, который читает со стандартного ввода . В редких случаях никто не будет готов предоставить данные, и сценарий должен отключиться . В случае тайм-аута скрипт должен выполнить некоторый код очистки. Какой лучший способ сделать это?
Этот сценарий должен быть очень переносимым , в том числе для Unix-систем 20-го века без компилятора C и для встраиваемых устройств, работающих под управлением busybox, поэтому нельзя полагаться на Perl, bash, любой скомпилированный язык и даже полную версию POSIX.2. В частности, $PPID
, read -t
и отлично POSIX-совместимые ловушки не доступны. Запись во временный файл также исключена; скрипт может работать, даже если все файловые системы смонтированы только для чтения.
Просто чтобы сделать вещи более сложными, я также хочу, чтобы сценарий был достаточно быстрым, когда он не истекает. В частности, я также использую скрипт в Windows (в основном в Cygwin), где fork и exec особенно низки, поэтому я хочу свести их использование к минимуму.
Короче говоря, у меня есть
trap cleanup 1 2 3 15
foo=`cat`
и я хочу добавить тайм-аут. Я не могу заменить cat
на read
встроенный. В случае тайм-аута я хочу выполнить cleanup
функцию.
Справочная информация: этот скрипт угадывает кодировку терминала, печатая некоторые 8-битные символы и сравнивая положение курсора до и после. В начале скрипта проверяется, что stdout подключен к поддерживаемому терминалу, но иногда среда врет (например, plink
устанавливает, TERM=xterm
даже если онTERM=dumb
вызывается с помощью ). Соответствующая часть скрипта выглядит так:
text='Éé' # UTF-8; shows up as Ãé on a latin1 terminal
csi='␛['; dsr_cpr="${csi}6n"; dsr_ok="${csi}5n" # ␛ is an escape character
stty_save=`stty -g`
cleanup () { stty "$stty_save"; }
trap 'cleanup; exit 120' 0 1 2 3 15 # cleanup code
stty eol 0 eof n -echo # Input will end with `0n`
# echo-n is a function that outputs its argument without a newline
echo-n "$dsr_cpr$dsr_ok" # Ask the terminal to report the cursor position
initial_report=`tr -dc \;0123456789` # Expect ␛[42;10R␛[0n for y=42,x=10
echo-n "$text$dsr_cpr$dsr_ok"
final_report=`tr -dc \;0123456789`
cleanup
# Compute and return initial_x - final_x
Как я могу изменить сценарий так, чтобы, если tr
через 2 секунды не было прочитано ни одного ввода, он был уничтожен и сценарий выполнил cleanup
функцию?