我有一个shell脚本,多数民众赞成从标准输入读取。在极少数情况下,将没有人准备提供输入,并且脚本必须超时。如果超时,脚本必须执行一些清理代码。最好的方法是什么?
该脚本必须具有很高的可移植性,包括没有C编译器的20世纪Unix系统和运行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
功能?