У мене є сценарій оболонки, який читається зі стандартного вводу . У рідкісних обставинах ніхто не буде готовий надати вхід, і сценарій повинен вимкнути час . У разі очікування сценарій повинен виконати деякий код очищення. Який найкращий спосіб зробити це?
Цей скрипт повинен бути дуже портативним , включаючи системи Unix 20 століття без компілятора С та вбудовані пристрої, на яких працює зайнята скринька, тому на 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
функцію?