我有一个 read_user_input.sh 脚本:
#!/bin/bash
# set -e
prompt="bla? [Y/n] "
while true; do
read -p "$prompt" -n 1 -s -t 3 reply
case $reply in
""|Y|y) echo "bla!!!"; break;;
N|n) echo "no bla :( you suck"; break;;
*) ;;
esac
done
正如我预期的那样工作 - 即
- 用户输入“Y”->bla
- 用户输入“y”->bla
- 用户按 Enter -> bla
- 超时 -> bla
但是,添加时set -e
- 读取以错误> 128结束。
从read --help
:
Exit Status:
返回代码为零,除非遇到文件结束、读取超时(这种情况下它大于 128)、发生变量分配错误或者向 -u 提供了无效的文件描述符作为参数。
克服这个问题的最佳方法是什么?
- 添加
|| true
似乎不正确,因为它会隐藏任何真正的错误。 - 我也不想删除
set -e
。 - 我想到另一件事就是处理它,
trap
但这似乎有点过头了
答案1
如果发生超时,则不要添加|| true
,而是将设置$reply
为:y
read -p "$prompt" -n 1 -s -t 3 reply || {
err=$?
if (( $err > 128 )) ; then
reply=y
else
exit $err
fi
}
答案2
这里有一个 hack,使用命令替换来分叉一个-e
未启用的子 shell。
#!/bin/bash
set -e
prompt="bla? [Y/n] "
while true; do
case $(read -p "$prompt" -n 1 -s -t 3 reply; echo $reply) in
""|Y|y) echo "bla!!!"; break;;
N|n) echo "no bla :( you suck"; break;;
*) ;;
esac
done
答案3
使用@choroba 答案,我将 switch case 更改为:
#!/bin/bash
set -e
prompt="bla? [Y/n] "
while true; do
read -p "$prompt" -n 1 -s -t 3 reply || (( $? > 128 ))
case $reply in
""|Y|y) echo "bla!!!"; break;;
N|n) echo "no bla :( you suck"; break;;
*) ;;
esac
done