begin
settings = `stty -g` # get current terminal settings
system('stty', 'eol', ' ') # make terminal recognize space as end-of-line
$/ = ' ' # set Ruby's input record separator to space
puts 'hit ^D to exit'
while input = gets(chomp: true)
p input: input
end
ensure
system('stty', settings) # revert terminal settings
end
在终端中运行上面的代码并输入foo bar baz(带尾随空格),得到:
hit ^D to exit
foo {:input=>"foo"}
bar {:input=>"bar"}
baz {:input=>"baz"}
另一种选择是通过调用stty或require 'io/console'(参见docs)将终端设置为 raw 模式。这将禁用所有行编辑功能(包括打印输入的字符)并将输入直接传递给Ruby。它为您提供了对输入的更多控制,但显然需要更多的工作才能获得我们习惯的行编辑功能。 termios的文档提供了更多信息。
require 'io/console'
def wait_for_space_key
puts "Press space to continue"
input = nil
while input != ' '
input = STDIN.getch
raise Interrupt if input.ord == 3 # Control-C has an ASCII value of 3
end
end
begin
# Your script goes here
puts "Welcome to my script!"
wait_for_space_key
puts "Thank you for pressing space!"
rescue Interrupt
puts "\nInterrupted by Control-C"
end
3条答案
按热度按时间jqjz2hbq1#
你可能需要使用
getch
。参见“Get single char from console immediately”并编写你自己的行输入。gets
不会对按下空格起作用,而是对整行输入进行分组,直到按下Enter。gets
文档中写道:从标准输入中返回(并赋值给$_)* 下一行 *...。
所以如果你按空格键,你可以在按回车键之前按退格键,做其他事情,Ruby不会对按下的空格起作用。
fnatzsnv2#
当你调用
gets
时,Ruby将行编辑委托给你的终端。使用默认设置,你的终端 * 缓冲 * 输入并提供一些基本的行编辑:它将输入的字符打印到屏幕上,并允许您通过del删除最后一个字符或通过^W删除整个单词(取决于您的终端)。Ruby不知道这些。它看不到你的编辑,也看不到结果字符串中的del控制字符。它唯一得到的是整个组合行。同样,Ruby不知道单独的按键,也不能自己拦截空格。
但幸运的是,终端是非常灵活的。几乎任何设置都可以配置,包括行尾字符。所以为了使空格像回车一样工作,我们必须调整终端设置!
这可以使用
stty
命令行工具完成。此外,您必须将Ruby的 input record separator$/
(默认为换行符)更改为空格,以便gets
和chomp
相应地运行。这里有一个快速而肮脏的例子:
在终端中运行上面的代码并输入
foo bar baz
(带尾随空格),得到:另一种选择是通过调用
stty
或require 'io/console'
(参见docs)将终端设置为 raw 模式。这将禁用所有行编辑功能(包括打印输入的字符)并将输入直接传递给Ruby。它为您提供了对输入的更多控制,但显然需要更多的工作才能获得我们习惯的行编辑功能。termios
的文档提供了更多信息。i2byvkas3#
这将只允许一个空格继续,同时仍然支持Control-C