vared
を使用してユーザー入力を求めるwhileループがあります。タイムアウトさせ、デフォルトの変数を実行し、一定時間後にユーザー入力がない場合はプロンプトにループバックする方法を探しています。 readコマンドとそのtimeout引数を知っていますが、これは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
あなたは次のようなことをすることができます:
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
変数をデフォルト値でprimingする代わりに、空の文字列でプライミングし、変数がまだ空の場合にのみデフォルト値に設定しますvared
が戻ります。
タイムアウトを処理するために、サブシェルで$TMOUT
特殊変数を使用します。これにより、zle
は$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
これらはスクリプトで機能しますが、 現在、インタラクティブシェルでは機能しませんvared
として、サブシェルでの実行を拒否することに注意してください。インタラクティブシェル内から実行する必要がある場合は、zsh
で修正されるまで、次を変更できます。
command=$(
...
)
に
command=$(default=$default zsh -c '
...
')