我想按下按键并按下q
字母后退出。
该脚本不等待密钥。如何纠正?
while read line
do
...
while :
do
read -n 1 key
if [[ $key = q ]]
then
break
fi
done
done < $1
答案 0 :(得分:4)
read
读取输入。
在您的脚本中,输入更改为$1
。
第一级while
循环正在从存储名称的文件中读取一行$1
,read -n 1 key
读取并存储下一行的第一个字符。同一个文件。
尝试一下:
while read line ; do
while : ; do
read -n 1 key <&1
if [[ $key = q ]] ; then
break
fi
done
done < $1
<&1
是标准输入。
答案 1 :(得分:0)
脚本不等待密钥。
因为命令read
从重定向文件获取其输入:
done < $1 ### Should be "$1".
两个read
命令(以及读取stdin的循环内的任何其他内容)都会使用该文件。
具有选项read
(和bash确实)的shell -u
的正确解决方案是定义每次读取时使用的fd
(文件描述符)当文件被重定向到某个fd
个数字(大于2)时:
while read -u 3 line ; do
while : ; do
read -u 1 -n 1 key
if [[ $key = q ]] ; then
break
fi
done
echo "$line"
done 3< "$1"
这使得第一次读取从fd 3
得到来自文件(done 3< "$1"
)的输入,第二次读取得到来自fd 1
(stdin)的输入。
对于POSIX shell,read没有-u
选项,我们需要执行一些重定向以获得相同的一般效果:
#!/bin/dash
while read line <&3; do
while : ; do
read key <&1
if [ "$key" = q ] ; then
break
fi
done
done 3< "$1"
可悲的是,这也会从读取中删除-n 1
选项,键盘上的每个键都必须按 Enter 。
要实际阅读一个字符,我们可能会使用dd
。我们还可以将实际终端设置为/dev/tty
(阻止任何其他重定向),如果我们需要隐藏文本类型(或密码),请使用stty -echo
:
#!/bin/dash
while read line <&3; do
while : ; do
stty raw -echo
key=$(dd bs=1 count=1 </dev/tty 2> /dev/null)
stty -raw echo
if [ "$key" = q ] ; then
break
fi
done
echo "$line"
done 3< "$1"
警告:设置stty raw
会阻止 CTRL - C 等键的影响(小心)。