我是红宝石的新手。我需要通过gets
命令接收密码作为输入。
如何在gets
通话
答案 0 :(得分:178)
也可以使用核心红宝石。
$ ri IO.noecho
(from ruby core)
------------------------------------------------------------------------------
io.noecho {|io| }
------------------------------------------------------------------------------
Yields self with disabling echo back.
STDIN.noecho(&:gets)
will read and return a line without echo back.
对于1.9.3(及更高版本),这需要您在代码中添加require 'io/console'
。
require 'io/console'
text = STDIN.noecho(&:gets)
答案 1 :(得分:30)
有一个名为highline的库,其工作原理如下:
require 'rubygems'
require 'highline/import'
password = ask("Enter password: ") { |q| q.echo = false }
# do stuff with password
答案 2 :(得分:18)
require 'io/console'
password = STDIN.noecho(&:gets).chomp
对于1.9.3(及更高版本),这需要您在代码中添加require 'io/console'
。
Ruby“Password”是另一种选择。
答案 3 :(得分:16)
正如其他人所提到的,您可以将IO#noecho
用于Ruby> = 1.9。如果您想支持1.8,可以使用read
内置shell函数:
begin
require 'io/console'
rescue LoadError
end
if STDIN.respond_to?(:noecho)
def get_password(prompt="Password: ")
print prompt
STDIN.noecho(&:gets).chomp
end
else
def get_password(prompt="Password: ")
`read -s -p "#{prompt}" password; echo $password`.chomp
end
end
现在获取密码非常简单:
@password = get_password("Enter your password here: ")
注意:在上面使用read
的实现中,如果您(或get_password
的某个其他客户端)传递了特殊shell字符,您将遇到麻烦提示(例如$
/ "
/ '
/ etc)。理想情况下,您应该在将提示字符串传递给shell之前将其转义。不幸的是,在Ruby 1.8中没有Shellwords
。幸运的是,backport the relevant bits自己很容易(特别是shellescape
)。有了这个,你可以做一点修改:
def get_password(prompt="Password: ")
`read -s -p #{Shellwords.shellescape(prompt)} password; echo $password`.chomp
end
我在下面的评论中提到了使用read -s -p
的几个问题:
嗯,1.8的情况有点笨拙;它不允许 反斜杠,除非你反击两次反斜杠:“反斜杠字符 `\'可用于删除下一个字符的任何特殊含义 读取和换行。“另外:”值中的字符 IFS变量用于将行拆分为单词。 “这应该 对于大多数小脚本来说可能都没问题,但你可能想要 对于大型应用程序而言更强大的东西。
我们可以通过卷起袖子并用stty(1)
努力解决这些问题来解决这些问题。我们需要做的概述:
当信号和/或异常中断时,我们还必须注意恢复终端设置。以下代码将正确处理作业控制信号(SIGINT / SIGTSTP / SIGCONT),同时仍可与任何当前的信号处理程序很好地协作:
require 'shellwords'
def get_password(prompt="Password: ")
new_sigint = new_sigtstp = new_sigcont = nil
old_sigint = old_sigtstp = old_sigcont = nil
# save the current terminal configuration
term = `stty -g`.chomp
# turn of character echo
`stty -echo`
new_sigint = Proc.new do
`stty #{term.shellescape}`
trap("SIGINT", old_sigint)
Process.kill("SIGINT", Process.pid)
end
new_sigtstp = Proc.new do
`stty #{term.shellescape}`
trap("SIGCONT", new_sigcont)
trap("SIGTSTP", old_sigtstp)
Process.kill("SIGTSTP", Process.pid)
end
new_sigcont = Proc.new do
`stty -echo`
trap("SIGCONT", old_sigcont)
trap("SIGTSTP", new_sigtstp)
Process.kill("SIGCONT", Process.pid)
end
# set all signal handlers
old_sigint = trap("SIGINT", new_sigint) || "DEFAULT"
old_sigtstp = trap("SIGTSTP", new_sigtstp) || "DEFAULT"
old_sigcont = trap("SIGCONT", new_sigcont) || "DEFAULT"
print prompt
password = STDIN.gets.chomp
puts
password
ensure
# restore term and handlers
`stty #{term.shellescape}`
trap("SIGINT", old_sigint)
trap("SIGTSTP", old_sigtstp)
trap("SIGCONT", old_sigcont)
end
答案 4 :(得分:9)
答案 5 :(得分:5)
对于ruby版本1.8(或Ruby< 1.9),我使用了read shell内置的@Charles。
将代码足以提示输入用户名&密码,其中用户名在输入时将回显到屏幕,但输入的密码将是静默的。
userid = `read -p "User Name: " uid; echo $uid`.chomp
passwd = `read -s -p "Password: " password; echo $password`.chomp