使用TCL命令行,有没有办法停止显示字符?

时间:2014-12-04 10:09:37

标签: c++ tcl

我建立一个工具是一个需要输入密码的命令。 我希望当我输入带有密码的命令时,命令行用" *"替换每个字符。或" ",所以命令和密码将无法观察!

是否有这样的命令告诉TCL解释器"从这一点开始,将每个字符显示为*",然后切换回常规模式?

任何其他建议也都很有价值。

2 个答案:

答案 0 :(得分:2)

在你的情况下,你应该完全控制"在您的终端上并禁用其默认的回显行为(在UNIX中,终端应该进入所谓的原始模式) 然后,您可以逐个读取字符(直到最大密码大小或按Enter键)并回显' *'每个按下的角色。 您在UNIX和Windows上都有工作代码示例如何执行此操作here 您可能还想阅读此链接echo-free password entry TCL wiki

proc enableRaw {{channel stdin}} {
   exec /bin/stty raw -echo <@$channel
}
proc disableRaw {{channel stdin}} {
   exec /bin/stty -raw echo <@$channel
}

enableRaw
set c [read stdin 1]
puts -nonewline $c
disableRaw
package require twapi
proc enableRaw {{channel stdin}} {
   set console_handle [twapi::GetStdHandle -10]
   set oldmode [twapi::GetConsoleMode $console_handle]
   set newmode [expr {$oldmode & ~6}] ;# Turn off the echo and line-editing bits
   twapi::SetConsoleMode $console_handle $newmode
}
proc disableRaw {{channel stdin}} {
   set console_handle [twapi::GetStdHandle -10]
   set oldmode [twapi::GetConsoleMode $console_handle]
   set newmode [expr {$oldmode | 6}] ;# Turn on the echo and line-editing bits
   twapi::SetConsoleMode $console_handle $newmode
}

enableRaw
set c [read stdin 1]
puts -nonewline $c
disableRaw

答案 1 :(得分:1)

(假设Linux。)到目前为止,处理终端密码的最简单方法是关闭输入的回显,但让终端处于熟化模式。它不会为每个输入的字符显示*,但它确实意味着您不必处理退格之类的事情(当用户意识到他们在点击返回之前输入错误的最后几个字符时)等。

exec /bin/stty -echo <@stdin
set password [gets stdin]
puts ""
exec /bin/stty echo <@stdin

如果你有Tcl 8.6,你可以通过这个程序轻松地使其更加强大:

proc getPassword {{prompt "Password: "}} {
    exec /bin/stty -echo <@stdin
    try {
        puts -nonewline $prompt
        flush stdout
        return [gets stdin]
    } finally {
        puts ""
        flush stdout
        exec /bin/stty echo <@stdin
    }
}

(可以使用catch和一些脚本来模拟try…finally,但这真的很烦人。)

如果你有一个GUI并且喜欢它,你可以通过将-show选项设置为非空(例如,*来显示星号)来创建密码输入框。