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

Posted

技术标签:

【中文标题】如何使用 msys (mingw32) 在 tcl 中转义字符串【英文标题】:how to escape string in tcl with msys (mingw32) 【发布时间】:2014-01-01 19:40:36 【问题描述】:

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

在 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 (msys/mingw) 中使用这个特殊形式的字符串:

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

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

a.txt
"

但是,我不知道如何在 tclsh 中完成这项工作。

% exec bash -c eval $ss

什么都不返回。我尝试了其他一些组合。没有工作。关于如何转义/取消转义这个的任何指示?

谢谢

【问题讨论】:

【参考方案1】:

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

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

大括号内的部分是shell语法,其余部分是Tcl语法;通过这样做,它将与(正确地使用 shell-quote)any 输入一起工作。请注意,Tcl 的大括号就像 bourne shell 单引号一样工作,除了它们是可嵌套的。


如果你想在 bash 中使用特殊形式,你可以将它替换到 bash 脚本中在 Tcl 中

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

但如果这种情况继续发生,可能是时候考虑您的方法是否正确……

【讨论】:

我不知道为什么会有一个名称相同但行为不一致的单独命令。唉,Unix 有时就是这样。 非常感谢您的回答。它在原始测试字符串上效果很好,但如果字符串中有结束行字符,它就会崩溃。请查看更新。 @TingL 这实际上是正确的; bash 有一个$'…' 的特殊形式,它的产生是合法的 bash 的printf %q 虽然我以前从未注意到过该表格,但它确实记录在手册页中。显然,it's part of SUS issue 7. 非常感谢您提供的详细信息。这真的很有帮助。关于特殊表格的使用,我还有最后一个问题。请查看更新。

以上是关于如何使用 msys (mingw32) 在 tcl 中转义字符串的主要内容,如果未能解决你的问题,请参考以下文章

使用 MinGW/MSYS 制作“xz-5.2.1”时出错

使用 MinGW 和 MSYS 找不到 .dll

MSYS2 使用

windows安装msys2 mingw64

是否可以在 msys /mingw 上模拟进程替换(使用 bash 3.x)

Msys/MinGW与Cygwin/gcc