如何用msys(mingw32)转义tcl中的字符串

时间:2014-01-01 19:40:37

标签: bash mingw tcl msys

我想让tcl在MSys / MinGW(来自mingw.org)下转义一个字符串。 tcl的版本来自mingw.org(截至2013年12月,通过mingw-get)。

在bash中,我可以用字符串(简化示例):

printf %q 'a \b $2'
printf '%q' "a \ b \' \" \$2"

返回:

a\ \\b\ \$2
a\ \\b\ \\\'\ \"\ \$2

分别

但是,如果字符串存储在变量中或从文件中读取,我无法使第二个示例在tclsh或tcl中工作。我尝试过的事情是:

% set s {a \b ' "  $2}
% printf %q $s
/usr/bin/printf: %q: invalid conversion specification
child process exited abnormally

(我猜这是因为msys printf.exe与tclsh不能很好地协同工作)。

%exec bash -c "printf %q $s"
/usr/bin/bash: -c: line 0: unexpected EOF while looking for matching `''
/usr/bin/bash: -c: line 1: syntax error: unexpected end of file

(在这里,我甚至不知道如何正确引用$ s,考虑$ s内的单引号和双引号)。知道如何使这项工作吗?

由于

- 更新 -

答案@Donal Fellows适用于原始字符串。我有:

% exec bash -c {printf %q "$0"} $s
a\ \\b\ \'\ \"\ \ \$2

但它对我第一次遇到的测试字符串不起作用。如果字符串中有一个结束行,答案似乎不起作用。

% set s1 {a \b ' "
 $2 }
% exec bash -c {printf %q "$0"} $s1 

我期待的是:

a\ \\b\ \'\ \"\ \n\ \$2

奇怪的是,上面的exec会返回:

$'a \\b \' "  \n $2 '

似乎搞砸了。有一个不需要的前导$',双引号"未正确转义。并且空白不会像以前一样转义为\。有什么想法吗?

- 更新2 -

正如@Donal Fellows所解释的那样,上面的字符串$'a \\b \' " \n $2 '是一个bash特殊的引用形式。我最后一个问题是如何在tcl中逃避/使用这种特殊形式。例如:

set s { ls
  echo '"' }
set ss [exec bash -c {printf %q "$0"} $s]

返回:

$' ls\n  echo \'"\' '

我可以在bash(msy​​s / mingw)中使用这个特殊的表单字符串:

eval $' ls\n  echo \'"\' '

执行两行命令(ls和echo'“'),并返回,例如:

a.txt
"

但是,我无法弄清楚如何在tclsh中完成这项工作。

% exec bash -c {eval $ss}

根本不返回任何内容。我尝试了其他一些组合。没有用。有关如何逃避/解除这一点的任何指示?

由于

1 个答案:

答案 0 :(得分:2)

printf既是msys 中的命令,也是 bash内置的命令。 只有bash内置支持%q这意味着从Tcl调用它比平常更棘手,因为你必须协商bash的引用。这需要这种相当尴尬的结构:

exec bash -c {printf %q "$0"} $s

大括号中的部分是shell语法,但其余部分是Tcl语法;通过这样做,它将与(以及正确的shell引用)任何输入一起使用。请注意,Tcl的大括号就像bourne shell单引号一样,除了它们是可嵌套的。


如果您想在bash中使用特殊表单,则将其替换为Tcl 中的bash脚本

set quoted [exec bash -c {printf %q "$0"} $s]
exec bash -c "eval $quoted"

(这没关系。printf %q完全引用了这项工作;这就是它的目的。)

如果你有一个复杂的脚本将使用你不想这样做的引用片段,你最终会再次将其作为参数传递,并在必要时使用另一个eval

exec bash -c {
    # You can get *really* complicated in here!
    eval eval "$0"
} $quoted

但如果这种情况继续下去,可能是时候考虑一​​下你的方法是否合适......