我有一个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
本文探讨了如何在Shell脚本中实现按键响应而无需按下Enter键。通过修改脚本和利用stty命令,可以创建非阻塞式的输入读取,从而在用户按下任意键时立即作出反应。
33万+

被折叠的 条评论
为什么被折叠?



