在静默模式下读取后,在bash脚本中捕获ctrl + c

时间:2014-03-27 06:16:15

标签: bash shell

我正在处理的脚本以静音模式读取单个字符并将其存储到$ c

下面是一个测试人员脚本,它做了一个例子:

    #!/bin/bash

    gracefulExit() {
          echo "exiting..."
          #other stuff would go here
          exit 1
    }

    trap gracefulExit INT

    while [ 1 = 1 ]
    do
          read -s -r -n1 c
          echo "character read"
    done

我遇到的问题是,如果你使用ctrl + c来打破脚本,那么shell会保持静默模式(我无法看到我输入的任何内容),并且它赢得了' t退出正常,直到我退出。我注意到这只发生在我捕获ctrl + c之后(没有陷阱,它从静音模式中踢出)。我的剧本要求我陷阱所以我可以清理。

这是4.2.10

有什么想法吗?

非常感谢你的帮助!

2 个答案:

答案 0 :(得分:2)

尝试在退出函数中重新启用tty echo:

#!/bin/bash

gracefulExit() {
      echo "exiting..."
      # reenable tty echo
      stty icanon echo echok
      exit 1
}

trap gracefulExit INT

while [ 1 = 1 ]
do
      read -s -r -n1 c
      echo "character read"
done

在我对OS X read的测试中禁用了这些设置:icanon echo echok。 您可以使用stty -a

检查系统

在调用脚本之前运行它,然后在脚本完成后再次运行它并检查输出中的差异以确定您编程的更改。然后重新设置更改的标志。

$ diff before.out after.out
2,3c2,3
< lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
<   -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
---
> lflags: -icanon isig iexten -echo echoe -echok echoke -echonl echoctl
>   -echoprt -altwerase -noflsh -tostop -flusho -pendin -nokerninfo

在这里你可以看到更改的标志:icanon, echo, echok被禁用了。您可以在开头标识“ - ”。

最后这是你的脚本的另一个版本,可以自动完成全部工作:

#!/bin/bash

# save the current tty flags
tty_flags=`stty -g`

gracefulExit() {
      echo "exiting..."
      # set the saved tty flags
      stty $tty_flags
      exit 1
}

trap gracefulExit INT

while [ 1 = 1 ]
do
      read -s -r -n1 c
      echo "character read"
done

答案 1 :(得分:0)

我猜你可以使用DD,虽然我不明白你想要改变的是什么。

c=$(stty raw;dd bs=1 count=1 if=$(tty) status=none;stty sane)

只要 stdin 输入单个字节,这至少会退出读取。只需输入密钥,即可设置 $c