如何使用空格键停止 Bash 脚本?

如何使用空格键停止 Bash 脚本?

我正在使用用 Bash 编写的魔方秒表,我想通过按空格键来停止它,因为当您必须尽快终止它时Ctrl+是不可行的。C

那么有没有办法仅使用空格键来停止该程序?

我看了看命令,kill但还是不明白。

秒表部分代码如下:

TMP0=$(date +%s%N)
while true; do
    TMP1=$(date +%s%N)
    DTMP=$(($TMP1-$TMP0))
    printf "\r$(($DTMP/1000000000)).${DTMP:(-9):2}"
done

答案1

Ctrl当您按下+时,您的终端会向前台进程组发送 SIGINT c。您可以将其配置为对任何字符执行此操作,但您希望在脚本退出时恢复旧设置。

#!/bin/bash

settings="$(stty -g)"
trap 'stty "$settings"' EXIT
stty intr ' '

TMP0=$(date +%s%N)
while true; do
    TMP1=$(date +%s%N)
    DTMP=$(($TMP1-$TMP0))
    printf '\r%s' "$(($DTMP/1000000000)).${DTMP:(-9):2}"
done

settings="$(stty -g)"保存旧设置;stty intr ' '使终端对Space而不是Ctrl+做出反应ctrap 'stty "$settings"' EXIT负责在脚本退出时恢复旧设置。

笔记:

  • 在陷阱代码中,stty $settings优于stty "$settings"。它是来自“总是引用“规则。引用可防止单词拆分和文件名生成(通配符),但某些实现stty可能需要单词拆分,对于这些实现,变量不能被引用。为了避免文件名生成产生的有害副作用,规格需要stty -g生成一个不会触发此功能的字符串。

    编辑:这是 POSIX 规范的一个缺陷。以上代码已修复。

  • 如果出现问题,并且您发现自己处于Space仍会生成 SIGINT 的交互式 shell 中,则需要手动调用stty intr ^C。命令中有空格,但请记住,您仍然可以通过按Ctrl+键入文字空格字符v Space

  • 我之所以使用是因为我认为静态格式和动态数据比您使用的动态格式更printf '\r%s' …符合“哲学” 。printf

Space而不是Ctrl+ c” 意味着当+Space变得特殊时,Ctrl它就c不再特殊了。你可以称它为缺陷,因为用户期望Ctrl+c保持特殊性。同时使两者变得特殊并非易事,我认为这不能通过配置终端来实现。

此替代版本几乎可以通过任何键停止,而Ctrl+c可以照常工作:

#!/bin/bash

while read -r -t 0.001; do :; done    # dump the buffer
TMP0=$(date +%s%N)
until read -r -n 1 -t 0.001; do
    TMP1=$(date +%s%N)
    DTMP=$(($TMP1-$TMP0))
    printf '\r%s' "$(($DTMP/1000000000)).${DTMP:(-9):2}"
done
echo

Space为了使其仅对您需要检查已读的内容做出反应:


until read -r -n 1 -t 0.001 && [ "$REPLY" = ' ' ]; do

Space请注意,停止脚本的机制现在与Ctrl+ 的c工作方式有很大不同。

答案2

如果你不需要秒表,毕竟你只是想知道最后花费的时间,那么你可以使用:

time read -r -n 1

它会给你如下输出:

time read -r -n 1

real    1m30.909s
user    0m0.000s
sys     0m0.000s

并且几乎可以通过任何按键停止(类似于 Kamil 的使用方式read

或者如果你只想要时间部分:

{ time read -r -n 1; } 2>&1 | grep real | awk '{ print $2 }'

礼貌里奇

相关内容