Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在ruby脚本中隐藏来自终端的密码输入_Ruby - Fatal编程技术网

如何在ruby脚本中隐藏来自终端的密码输入

如何在ruby脚本中隐藏来自终端的密码输入,ruby,Ruby,我对ruby是新手。我需要通过get命令接收密码作为输入 如何隐藏在终端中键入的密码输入,在getcall期间,有一个名为的库,其工作原理如下: require 'rubygems' require 'highline/import' password = ask("Enter password: ") { |q| q.echo = false } # do stuff with password require 'io/console' password = STDIN.getpass("

我对ruby是新手。我需要通过
get
命令接收密码作为输入

如何隐藏在终端中键入的密码输入,在
get
call

期间,有一个名为的库,其工作原理如下:

require 'rubygems'
require 'highline/import'

password = ask("Enter password: ") { |q| q.echo = false }
# do stuff with password
require 'io/console'
password = STDIN.getpass("Password:")
@eclectic923答案中的最佳方法:
需要“io/控制台”
password=STDIN.noecho(&:gets).chomp
对于1.9.3(及以上版本),这要求您在代码中添加
require'io/console'

require 'io/console'
text = STDIN.noecho(&:gets)
原始答复:
Ruby“”是另一种选择。

也可以使用核心Ruby

$ 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)

正如其他人提到的,您可以使用for Ruby>=1.9。如果希望支持1.8,可以使用内置的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\u password
的其他客户端)在提示符中传递特殊的shell字符(例如
$
/
/
/etc),您将遇到麻烦。理想情况下,您应该在将提示字符串传递给shell之前对其进行转义。不幸的是,在Ruby 1.8中不可用。幸运的是,这对您自己来说很容易(特别是)。有了它,您可以进行以下轻微修改:

  def get_password(prompt="Password: ")
    `read -s -p #{Shellwords.shellescape(prompt)} password; echo $password`.chomp
  end

我在下面的评论中提到了使用
read-s-p
的几个问题:


嗯,1.8这个案子有点不对劲,它不允许 反斜杠,除非打反斜杠两次:“反斜杠字符 `\'可用于删除下一个字符的任何特殊含义 请阅读并进行换行。”另外:“值中的字符 IFS变量用于将行拆分为单词。“这应该 对于大多数小脚本来说可能很好,但您可能需要 对于更大的应用程序更健壮的东西

我们可以卷起袖子努力解决其中一些问题。我们需要做的概述如下:

  • 存储当前终端设置
  • 回音
  • 打印提示并获取用户输入
  • 恢复终端设置
我们还必须注意在被信号和/或异常中断时恢复终端设置。以下代码将正确处理作业控制信号(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
对于ruby版本1.8(或ruby<1.9),我使用了@Charles提到的shell内置

输入足以提示输入用户名和密码的代码,输入时用户名将回显到屏幕上,但输入的密码将保持沉默

 userid = `read -p "User Name: " uid; echo $uid`.chomp
 passwd = `read -s -p "Password: " password; echo $password`.chomp

从Ruby 2.3.0版开始,您可以像下面这样使用
IO#getpass
方法:

require 'rubygems'
require 'highline/import'

password = ask("Enter password: ") { |q| q.echo = false }
# do stuff with password
require 'io/console'
password = STDIN.getpass("Password:")

请参阅标准库文档中的方法。

谢谢。我正是在寻找这个答案。这个答案应该被弃用,取而代之的是@eclectic923 core ruby解决方案。对于1.9.3,这要求您在代码中添加
require'io/console'
。这比任何gem选项通常都要好。我无法+1这个答案就足够了。这比包含任何一天都有额外的宝石!别忘了.chomp你的输入!pass=STDIN.noecho(&:get).chomp你是如何让它在Cygwin中工作的?
tmp.rb:2:in'noecho:tmp中的错误文件描述符(Errno::EBADF)。rb:2:in
嗯,1.8的大小写有点笨拙;它不允许反斜杠,除非你打两次反斜杠:反斜杠字符“\”可用于删除下一个读取字符和行继续的任何特殊含义。”此外:“IFS变量值中的字符用于将行拆分为单词。“对于大多数小脚本来说,这应该很好,但对于较大的应用程序,您可能需要一些更健壮的东西。是否可能重复使用getpass来回显特定字符,如*?