Tôi có một kịch bản shell đang đọc từ đầu vào tiêu chuẩn . Trong những trường hợp hiếm hoi, sẽ không có ai sẵn sàng cung cấp đầu vào và kịch bản phải hết thời gian . Trong trường hợp hết thời gian, tập lệnh phải thực thi một số mã dọn dẹp. Cách tốt nhất để làm điều đó là gì?
Tập lệnh này phải rất dễ mang theo , bao gồm các hệ thống unix thế kỷ 20 không có trình biên dịch C và các thiết bị nhúng đang chạy busybox, vì vậy Perl, bash, bất kỳ ngôn ngữ được biên dịch nào và thậm chí cả POSIX.2 đều không thể dựa vào. Đặc biệt, $PPID
, read -t
và bẫy hoàn hảo POSIX-compliant không có sẵn. Viết vào một tập tin tạm thời cũng được loại trừ; tập lệnh có thể chạy ngay cả khi tất cả các hệ thống tập tin được gắn ở chế độ chỉ đọc.
Chỉ để làm cho mọi thứ trở nên khó khăn hơn, tôi cũng muốn kịch bản nhanh chóng hợp lý khi nó không hết thời gian. Đặc biệt, tôi cũng sử dụng tập lệnh trong Windows (chủ yếu ở Cygwin), trong đó fork và exec đặc biệt thấp, vì vậy tôi muốn giữ mức sử dụng của chúng ở mức tối thiểu.
Tóm lại, tôi có
trap cleanup 1 2 3 15
foo=`cat`
và tôi muốn thêm thời gian chờ. Tôi không thể thay thế cat
bằng tích read
hợp. Trong trường hợp hết thời gian, tôi muốn thực hiện cleanup
chức năng.
Bối cảnh: tập lệnh này đoán mã hóa của thiết bị đầu cuối bằng cách in một số ký tự 8 bit và so sánh vị trí con trỏ trước và sau. Sự khởi đầu của các bài kiểm tra kịch bản mà thiết bị xuất chuẩn được kết nối với một thiết bị đầu cuối được hỗ trợ, nhưng đôi khi môi trường đang nói dối (ví dụ: plink
đặt TERM=xterm
ngay cả khi nó được gọi vớiTERM=dumb
). Phần có liên quan của kịch bản trông như thế này:
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
Làm cách nào tôi có thể sửa đổi tập lệnh để nếu tr
không đọc bất kỳ đầu vào nào sau 2 giây, tập lệnh sẽ bị hủy và tập lệnh thực thi cleanup
chức năng?