在while循环中等待按键并停止脚本

时间:2016-05-15 19:17:24

标签: bash

我想按下按键并按下q字母后退出。 该脚本不等待密钥。如何纠正?

while read line
do
    ...
    while :
    do
        read -n 1 key

        if [[ $key = q ]]
        then
            break
        fi
    done
done < $1

2 个答案:

答案 0 :(得分:4)

read读取输入。

在您的脚本中,输入更改为$1

第一级while循环正在从存储名称的文件中读取一行$1read -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 等键的影响(小心)。