将字符串发送到管道而不回显终端

时间:2014-07-20 06:50:35

标签: ruby

我正在尝试为命令行工具pwsafe编写一个简单的包装器。我正在做这样的事情:

def fetch_app_password
  master_password = driver.get # this reliably fetches the correct master password
  open( "| pwsafe", 'r+' ) do |pwsafe-pipe|
    pwsafe_pipe.write(master_password + "\n")
    app_password = pwsafe_pipe.read()
    return app_password
  end
  raise 'an error occurred'
end

此代码是正确的,因为它获取正确的应用程序密码。麻烦的是你可以在终端上看到交换:

enter passphrase for /home/user/pwsafe.dat: $oup3rSeKr!T

这对肩膀冲浪者来说并不是那么安全。我想阻止发送到管道的密码以明文形式在我的终端上结束。我很感激建议。

更新:我试过的一些代码

def fetch_app_password
  master_password = driver.get
  open( "| pwsafe", 'r+' ).noecho do |pwsafe-pipe|
    pwsafe_pipe.write(master_password + "\n")
    app_password = pwsafe_pipe.read()
    return app_password
  end
  raise 'an error occurred'
end

def fetch_app_password
  master_password = driver.get
  open3.Popen("pwsafe") do |stdin, stdout, stderr, ignored|
    stdin.noecho { |stdin| stdin.write( master_password + "\n") }
    app_password = stdout.noecho { |stdout| stdout.readline() }
    return app_password
  end
  raise 'an error occurred'
end

当我尝试调用inappropriate ioctl for device (errno::NOTTY)时,这两个实现都会引发异常noecho。在外部控制台上调用noecho无效。

1 个答案:

答案 0 :(得分:1)

我认为问题在于pwsafe本身。为了说明原因,我用Ruby编写了一个小测试脚本,读取stdin并写入stdout和stderr:

# streams.rb
STDERR.print "Input text to reverse: "
STDOUT.puts STDIN.read.reverse

然后我使用open3

运行它
require 'open3'
Open3.popen3('./streams.rb') do |stdin, stdout, stderr, thr|
  stdin.write("Super secret password")
  stdin.close

  puts "OUT: #{stdout.read}"
  puts "ERR: #{stderr.read}"
end

出现的唯一输出是两个puts

OUT: drowssap terces repuS
ERR: Input text to reverse:

如果你的脚本仍在向命令行输出其他内容,要么你没有向我们展示所有相关的代码,要么问题完全在Ruby之外。