【问题标题】:Hiding User Input隐藏用户输入
【发布时间】:2011-03-08 23:05:26
【问题描述】:

我正在尝试获取一个脚本,该脚本可在本机 Windows shell 和 cygwin shell(通过 ssh)中运行,提示输入并读取用户输入的密码。到目前为止,我已经尝试了以下方法:

  1. 使用 Term::ReadKey 并将 ReadMode 设置为 'noecho'
    • 结果:返回错误GetConsoleMode failed 并退出
  2. 使用 Term::ReadPassword::Win32
    • 结果:挂起并且从不提供提示或读取输入
  3. 使用 IO::Prompt
    • 结果:返回错误Cannot write to terminal 并退出
  4. 使用 Term::InKey
    • 结果:返回错误Not implemented on MSWin32: The handle is invalid 并退出

所有这些都在本机 Windows shell(命令提示符或电源 shell)中工作,但是当我在与服务器的 ssh 会话中时,它们都不起作用。

真的,这是我最感兴趣的,让它在远程 ssh 会话中工作。

我通过安装在 Windows 服务器 (2003 R2) 上的 cygwin 获取 ssh。我使用的是草莓 perl 而不是 cygwin perl(cygwin perl 破坏了我需要在 Windows 中本地运行的其他 perl 脚本,而不是通过 ssh)。

我的最佳猜测是 cygwin+Windows 与草莓 perl 搞混了,以至于它无法判断它所处的环境类型。我正在寻找替代 sshd+Windows 解决方案来探索这一点。

这些是我在搜索中能够找到的所有方法。是否还有其他人可以建议其他方法来隐藏用户输入?

【问题讨论】:

  • “它们都不起作用”是什么意思?是用户没有得到提示还是用户的输入没有隐藏?
  • 从ssh会话测试,第一种方法返回错误GetConsoleMode failed并退出,第二种方法挂起并且从不提供提示或读取输入,第三种方法返回错误Cannot write to terminal并退出,第四种方法返回错误Not implemented on MSWin32: The handle is invalid 并退出。在本机 Windows shell 中,除了返回相同错误的第三种方法外,它们都可以工作,因此可能我只是没有正确调用它。
  • 请注意:当在 cygwin 下编译时,链接库中会附带大量 UNIXish 仿真:例如诸如 cygwinsshd 正在使用的 UNIXish pty 接口之类的东西。不幸的是,您使用的 Perl 尚未使用 cygwin 接口进行编译,并且要与其接口,您需要 cygwin 仿真库。你知道为什么你的脚本不能使用 cygwin 下编译的 Perl 运行吗?

标签: windows perl ssh cygwin hidden


【解决方案1】:
use Term::ReadKey;
print "Please enter your artifactory user name:";
$username = <STDIN>;
chomp($username);
ReadMode('noecho'); # don't echo
print "Please enter your artifactory password:";
$password = <STDIN>;
chomp($password);
ReadMode(0); #back to normal
print "\n\n";

【讨论】:

    【解决方案2】:

    我会尝试在有效的会话期间输出环境变量 (%ENV),然后在无效的会话期间再次输出。我发现,在处理终端 IO 时,您必须根据 $^O 变量和 $ENV{SESSIONNAME}(在 Windows 中)等内容仔细调整“TERM”变量。

    【讨论】:

    • 在 cygwin ssh 会话中,TERM 设置为 xterm,而在本机 Windows shell 中,它设置为 dumb。那里有什么建议吗?谢谢。
    【解决方案3】:

    Term::ReadKey 的 ReadMode(4) 怎么样?我刚刚在个人项目中使用它,找到了答案here

    适用于 cygwin / win7,但不能保证原生 windows shell。

    use strict;
    use warnings;
    use Term::ReadKey;
    
    sub get_input {
      my $key = 0;
      my $user_input = "";
    
     # disable control keys and start reading keys until enter key is pressed (ascii 10)
     ReadMode(4);
     while (ord($key = ReadKey(0)) != 10)
       {
         if (ord($key) == 127 || ord($key) == 8) {
           # backspace / del was pressed.  remove last char and move cursor back one space.
           chop ($user_input);
           print "\b \b";
         } elsif (ord($key) < 32) {
             # control characters, do nothing
         } else {
             $user_input = $user_input . $key;
             print "*";
         }
       }
      ReadMode(0);
      return $user_input;
    }
    
    # variables
    my $password = "";
    my $username = "";
    
    print "\nPlease input your username: ";
    $username = get_input();
    print "\nHi, $username\n";
    
    print "\nPlease input your password: ";
    $password = get_input();
    

    【讨论】:

      猜你喜欢
      • 2012-06-16
      • 2018-08-27
      • 2022-11-15
      • 2017-06-27
      • 1970-01-01
      • 2013-07-22
      • 2011-12-06
      • 2021-03-15
      • 2015-11-09
      相关资源
      最近更新 更多