1

考虑以下代码:

puts "What show command would you like to execute?"
set cmd [gets stdin]

proc makeLC {str} {
   puts "begin"
   puts $str
   set lStr [string tolower $str]
   set lStr [string trim $lStr]
   puts "after low and trim"
   puts $lStr
   set lenStr [string length $lStr]
   for {set i 0} {$i < $lenStr} {incr i} {
      puts [string index $lStr $i]
   }
   return $lStr
}

set lcmd [makeLC $cmd]

当用户键入“test12345”然后退格显示“test123”然后添加“67”以最终显示“test12367” puts $lStr 返回“test12367”但“for”循环将显示“test12345 67”“12345”之间的空格我相信“67”是“\b\b”。

为什么不一致?
以及如何确保在传递 $lStr 时分配了“test12367”而没有分配“test12345 67”

4

2 回答 2

2

通常,Unix 上的 Tcl 程序在终端中以“cooked”模式运行。熟模式终端为您处理所有行编辑;您可以简单地阅读完成的行,因为它们是生成的。使用熟模式非常容易。但是您也可以将终端置于原始模式,其中(通常)应用程序决定自己直接处理所有击键。(通常同时关闭字符的回显,以便应用程序处理输出端和输入端。)这是 vi 和 emacs 等编辑器所做的,readline 库也是如此(在许多程序中使用,如巴什)。原始模式很多更繁琐的工作,但给你更多的控制。与此不同的是,输入的内容是否被回显以便可以看到;例如,还有无回声的熟模式,这对密码很有用。

在您的情况下,听起来很像终端处于回显原始模式(不寻常!)并且您的应用程序希望它处于回显熟模式;当按下删除键(或者可能是退格键;那里有很多复杂性!)时,您将获得从键盘发送的实际字符,这是非常不寻常的。要恢复理智,请执行以下操作:

# No raw, Yes echo
exec stty -raw echo <@stdin >@stdout

在 Windows 上有一些概念上相似的东西,但它通过完全不同的系统调用工作。

于 2013-08-15T10:34:45.820 回答
0

考虑使用tclreadlinewhich wraps GNU readline 为交互式命令行编辑提供全面支持。

依赖于外部工具存在的另一个解决方案是将对 Tcl shell 的调用包装在rlwrap

rlwrap tclsh /path/to/script/file.tcl
于 2013-08-15T09:42:40.400 回答