문제
Enter를 누르지 않고 Ruby와 함께 터미널에서 단일 키보드 문자를 얻으려면 어떻게해야합니까? 나는 시도했다 Curses::getch
, 그러나 그것은 실제로 나를 위해 효과가 없었습니다.
해결책
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/2999
#!/usr/bin/ruby
begin
system("stty raw -echo")
str = STDIN.getc
ensure
system("stty -raw echo")
end
p str.chr
(내 OS X 시스템에서 테스트 된 것은 모든 루비 플랫폼에 휴대가되지 않을 수 있습니다). 보다 http://www.rubyquiz.com/quiz5.html Windows를 포함한 몇 가지 추가 제안.
다른 팁
Ruby 2.0.0 이후 STDLIB에는이 기능을 사용하여 'IO/Console'이 있습니다.
require 'io/console'
STDIN.getch
@jay는 큰 대답을했지만 두 가지 문제가 있습니다.
- 기본 tty 상태를 엉망으로 만들 수 있습니다.
- 당신은 제어 문자를 무시합니다 (sigint 등의 경우^c).
이를위한 간단한 수정은 이전 TTY 상태를 저장하고 다음 매개 변수를 사용하는 것입니다.
-icanon
- 표준 입력을 비활성화합니다 (처리 및 킬 처리);isig
- 특수 제어 문자에 대해 문자 검사를 활성화 할 수 있습니다.
결국에는 다음과 같은 기능이 있습니다.
def get_char
state = `stty -g`
`stty raw -echo -icanon isig`
STDIN.getc.chr
ensure
`stty #{state}`
end
원시 모드 (stty raw -echo
) 불행히도 Control-C가 Sigint가 아닌 캐릭터로 보내도록합니다. 따라서 위와 같은 입력 차단을 원하지만 사용자가 대기중인 동안 프로그램을 중지하기 위해 Control-C를 누르도록 허용하는 경우 다음을 수행하십시오.
Signal.trap("INT") do # SIGINT = control-C
exit
end
그리고 비 블로킹 입력을 원한다면, 즉, 사용자가 키를 누른지 정기적으로 확인하지만 그 동안 다른 일을하십시오. 그러면 다음을 수행 할 수 있습니다.
require 'io/wait'
def char_if_pressed
begin
system("stty raw -echo") # turn raw input on
c = nil
if $stdin.ready?
c = $stdin.getc
end
c.chr if c
ensure
system "stty -raw echo" # turn raw input off
end
end
while true
c = char_if_pressed
puts "[#{c}]" if c
sleep 1
puts "tick"
end
TTY는 잠시 동안 원시 모드에 있기 때문에 비 블로킹 버전에 특수 Sigint 핸들러가 필요하지 않습니다.
참고 : 이것은 오래된 답변이며 솔루션은 더 이상 대부분의 시스템에서 작동하지 않습니다.
그러나 다른 방법이 작동하지 않는 일부 환경에는 그 대답이 여전히 유용 할 수 있습니다. 아래의 의견을 읽으십시오.
먼저 Highline을 설치해야합니다.
gem install highline
그런 다음 Highline 메소드가 귀하에게 효과가 있는지 시도하십시오.
require "highline/system_extensions"
include HighLine::SystemExtensions
print "Press any key:"
k = get_character
puts k.chr
그리고 당신이 건축중인 경우 저주 응용 프로그램, 전화가 필요합니다
nocbreak
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/curses.html#method-c-cbreak