Saya memiliki skrip shell yang membaca dari input standar . Dalam keadaan yang jarang terjadi, tidak akan ada orang yang siap memberikan masukan, dan skrip harus berhenti . Dalam hal batas waktu, skrip harus menjalankan beberapa kode pembersihan. Apa cara terbaik untuk melakukan itu?
Skrip ini harus sangat portabel , termasuk ke sistem unix abad ke-20 tanpa kompiler C dan ke perangkat tertanam yang menjalankan busybox, sehingga Perl, bash, bahasa yang dikompilasi, dan bahkan POSIX.2 lengkap tidak dapat diandalkan. Secara khusus, $PPID
, read -t
perangkap dan sempurna POSIX-compliant tidak tersedia. Menulis ke file sementara juga dikecualikan; skrip dapat berjalan bahkan jika semua sistem file dipasang hanya-baca.
Hanya untuk membuat segalanya lebih sulit, saya juga ingin skrip menjadi cukup cepat ketika tidak ada waktu habis. Secara khusus, saya juga menggunakan script di Windows (terutama di Cygwin), di mana garpu dan exec sangat rendah, jadi saya ingin menjaga penggunaannya seminimal mungkin.
Singkatnya, saya punya
trap cleanup 1 2 3 15
foo=`cat`
dan saya ingin menambahkan batas waktu. Saya tidak bisa mengganti cat
dengan read
built-in. Dalam hal timeout, saya ingin menjalankan cleanup
fungsinya.
Latar Belakang: skrip ini menebak pengodean terminal dengan mencetak beberapa karakter 8-bit dan membandingkan posisi kursor sebelum dan sesudah. Awal tes skrip yang stdout terhubung ke terminal yang didukung, tetapi kadang-kadang lingkungan berbohong (misalnya plink
mengatur TERM=xterm
bahkan jika itu dipanggil denganTERM=dumb
). Bagian yang relevan dari skrip terlihat seperti ini:
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
Bagaimana saya bisa memodifikasi skrip sehingga jika tr
belum membaca input apa pun setelah 2 detik, skrip tersebut dimatikan dan skrip mengeksekusi cleanup
fungsinya?