linux脚本按键,关于bash:shell脚本响应按键

本文探讨了如何在Shell脚本中实现按键响应而无需按下Enter键。通过修改脚本和利用stty命令,可以创建非阻塞式的输入读取,从而在用户按下任意键时立即作出反应。

我有一个shell脚本,基本上说

while true; do

read -r input

if ["$input" ="a"]; then

echo"hello world"

fi

done

这一切都很好,很好,但我刚刚意识到,在这种情况下,必须击中enter是一个严重的问题。我需要的是脚本在按键时响应,而不必按Enter键。

在shell脚本中是否有实现此功能的方法?

如果这是您的真实代码,请注意,在if条件下,[和]周围缺少空格。

不,这不是我真正的密码。但是谢谢你的小费

脚本的应用程序在显示中。前一个控制面板是用鼠标制作的,点击作为操作机制。但他们想为数据存储增加一个硬币操作。原来的计算机死机了,运行的是Windows98,而硬件或软件都不能在新的Windows操作系统上运行。因此,我推断了各个操作,并重新连接了一个键盘以提供IO功能。但当我回家写脚本的其余部分(远程登录)时,它似乎不起作用。观众是儿童。存在随机IO的重大风险

在Linuxshell脚本中如何提示输入的可能副本?

特殊密钥子集:stackoverflow.com/questions/22842896/…

read -rsn1

希望只有一封信(不要等待提交),保持沉默(不要写回那封信)。

伙计,我昨晚试过了,好像没用。但是延迟可能是个问题。我再试一次。

为我工作。

@j0h是否要在循环中继续,因为这将阻止直到输入某些内容?

我想让它问用户:在完成每一步之后,一遍又一遍地问他们为什么要这样做。不幸的是,我还在家里,在一台Windows电脑上。

如果需要检查输入是否可用,请尝试添加-t 0.01以等待一小部分秒,然后在没有等待按键的情况下放弃。如果你想要一个很紧的循环,较小的数字可能还是完全可以的。非正式实验表明0.00001有效,但0.000001太小。

我使用这个命令创建了一个自我更新状态信息脚本,它可以接受键输入来更改显示。read -rsn1 -t 5 key读取$key的一个键并退出,否则等待5秒重新呈现状态信息。非常方便,谢谢。

所以最后的工作片段是:

#!/bin/bash

while true; do

read -rsn1 input

if ["$input" ="a" ]; then

echo"hello world"

fi

done

另一种方法,以非阻塞方式(不确定您是否需要它)。您可以使用stty将最小读取时间设置为0。(如果在之后不使用stty sane,则有点危险)

stty -icanon time 0 min 0

然后像正常一样运行循环。不需要-R。

while true; do

read input

if ["$input" ="a"]; then

echo"hello world"

fi

done

重要!完成非阻塞后,必须记住将stty设置回正常使用状态。

stty sane

如果你不这样做,你将看不到终端上的任何东西,它将似乎挂起。

您可能希望为ctrl-c包含一个陷阱,就好像在您将stty恢复正常之前脚本已经退出,您将无法看到您键入的任何内容,并且它将显示终端已经冻结。

trap control_c SIGINT

control_c()

{

stty sane

}

另外,你可能想在你的脚本中加入一个睡眠语句,这样你就不会耗尽你所有的CPU,因为这将继续以尽可能快的速度运行。

sleep 0.1

P.S.S.看来,挂起的问题只有在我使用过的时候才出现——可能不需要像以前那样使用echo。我将把它留在答案中,因为将stty重置为默认值以避免将来的问题仍然是好的。如果您不希望您键入的内容出现在屏幕上,可以使用-echo。

您可以使用此getkey功能:

getkey() {

old_tty_settings=$(stty -g)   # Save old settings.

stty -icanon

Keypress=$(head -c1)

stty"$old_tty_settings"      # Restore old settings.

}

它暂时关闭终端设置中的"规范模式"(stty -icanon然后返回"head"(shell内置)的输入,其中-c1选项返回一个字节的标准输入。如果您不包括"stty-icanon",那么脚本将回响按键的字母,然后等待返回(而不是我们想要的)。"head"和"stty"都是shell内置命令。收到按键后,保存和恢复旧的终端设置非常重要。

然后,getkey()可以与"case / esac号"语句结合使用,用于从条目列表中交互式选择一个键:例子:

case $Keypress in

[Rr]*) Command response for"r" key ;;

[Ww]*) Command response for"w" key ;;

[Qq]*) Quit or escape command ;;

esac

这种getkey()/case-esac组合可用于使许多shell脚本交互。我希望这有帮助。

getkey()的可用性有所不同。

在我的项目中,我有一种方法可以做到这一点:https://sourceforge.net/p/playshell/code/ci/master/tree/source/keys.sh

每次调用密钥读取时,它都读取一个密钥。对于特殊键,将运行一个特殊的解析循环,以便能够解析它们。

这是它的关键部分:

if read -rn 1 -d ''"${T[@]}""${S[@]}" K; then

KEY[0]=$K

if [[ $K == $'\e' ]]; then

if [[ BASH_VERSINFO -ge 4 ]]; then

T=(-t 0.05)

else

T=(-t 1)

fi

if read -rn 1 -d ''"${T[@]}""${S[@]}" K; then

case"$K" in

\[)

KEY[1]=$K

local -i I=2

while

read -rn 1 -d ''"${T[@]}""${S[@]}""KEY[$I]" && \

[[ ${KEY[I]} != [[:upper:]~] ]]

do

(( ++I ))

done

;;

O)

KEY[1]=$K

read -rn 1 -d ''"${T[@]}" 'KEY[2]'

;;

[[:print:]]|$'\t'|$'\e')

KEY[1]=$K

;;

*)

__V1=$K

;;

esac

fi

fi

utils_implode KEY __V0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值