Tcl/Expect能否生成Shell可解析的参数格式用于send命令?
问题:将TCL参数转为Shell友好格式通过send传递
现有如下简短Expect程序:
#!/usr/bin/expect puts $::argc puts $::argv
调用该程序时,能正确识别参数数量,但argv数组的原生Tcl输出无法直接传递给Shell:
./Test.exp x y z "a b c" 4 x y z {a b c}
需求是:让TCL输出Shell友好格式的参数,以便通过send命令传递给已启动的Shell(如bash)。注:已知可直接用spawn或exec传递参数,但需要通过send向交互式Shell发送命令序列并记录会话,因此需要正确的Shell引用格式。
解决方案
可以编写一个Tcl过程对每个参数进行Shell转义处理,生成符合Shell语法的字符串,实现代码如下:
#!/usr/bin/expect proc shell_escape {arg} { # 处理空参数,返回空引号避免Shell忽略 if {$arg eq ""} { return '""' } # 无特殊字符的参数直接返回,减少冗余引号 if {![string match {*[ \t\n\\"'$`()<>|&;*?#~]} $arg]} { return $arg } # 用单引号包裹参数,同时转义内部的单引号(Shell中'\''表示单引号) set escaped [string map {' '\\''} $arg] return '$escaped' } # 遍历所有参数,转义后拼接成Shell友好的参数列表 set shell_args [join [lmap arg $::argv {shell_escape $arg}] " "] # 测试输出转义后的参数 puts $shell_args # 示例:向启动的bash发送带转义参数的命令 spawn bash send "echo $shell_args\r" interact
代码说明
shell_escape过程会根据参数内容自动选择处理方式:空参数返回"",无特殊字符的参数直接返回,含特殊字符的参数用单引号包裹并转义内部单引号,确保Shell能正确解析。lmap遍历所有输入参数,逐个转义后用空格拼接成完整的参数字符串,直接嵌入send的命令中即可。
测试运行脚本:
./Test.exp x y z "a b c" 'hello'world' "test$var"
生成的Shell参数字符串为:
x y z 'a b c' 'hello'\''world' '"test$var"'
发送给bash后,echo会正确识别所有参数,包括带空格、特殊字符的参数。
内容的提问来源于stack exchange,提问作者merlin2011
相关产品推荐
相关产品推荐

