我有一个 while 循环使用vared
提示用户输入。我正在寻找一种方法让它超时,执行默认变量并在一定时间后没有用户输入时循环回到提示。我知道读取命令及其超时参数,但这是否可以通过vared
?
另外,有没有办法设置默认值,vared
使其不打印到提示符?
local command
while :
do
echo "Enter a command or type 'quit' to exit:"
vared -p "[*]: " command
if [ "$command" = "quit" ]; then
break
else
run command
fi
clear
done
答案1
你可以这样做:
default=foobar
if
command=$(
saved_settings=$(stty -g)
trap 'stty $saved_settings; exit 1' ALRM
v=
TMOUT=10 vared -p "Enter a command [$default]: " v &&
printf %s $v
)
then
command=${command:-$default}
printf 'Got: "%s"\n' $command
else
print timeout
fi
代替启动具有默认值的变量,我们用空字符串填充它,并且仅当vared
返回后变量仍然为空时才将其设置为默认值。
为了处理超时,我们$TMOUT
在子 shell 中使用特殊变量,这会导致在几秒钟zle
后退出该子 shell $TMOUT
。
这是 10 秒的全局超时。另一种方法可以使用终端线路规则字符间超时(stty time x
,以x
十分之一表示),为用户提供足够的时间来输入大型命令,但在闲置 3 秒后超时:
default=foobar
if
command=$(
saved_settings=$(stty -g)
trap 'stty $saved_settings' EXIT INT TERM ALRM
zle-line-init() stty -icanon time 30 min 0 <&2
zle -N zle-line-init
v=
vared -p "Enter a command [$default]: " v &&
printf %s $v
)
then
command=${command:-$default}
printf 'Got: "%s"\n' $command
else
print
print timeout
fi
请注意,虽然这些在脚本中工作,它目前在交互式 shell 中不起作用因为vared
将拒绝在子外壳中运行。如果您需要从交互式 shell 中运行它,直到在 中修复该问题zsh
,您可以更改:
command=$(
...
)
到
command=$(default=$default zsh -c '
...
')