代码之家  ›  专栏  ›  技术社区  ›  Gary

在exec命令中处理单引号和$

tcl
  •  1
  • Gary  · 技术社区  · 3 年前

    我正在尝试执行这行代码,在这里添加的“音频”后面没有换行符,只是为了不显示水平滚动条:

    [exec mediainfo --Output=$'General;File Name: %FileName%\nAudio;
     Duration: %Duration/String3%' 01_gen/01001.mp3]
    

    它在Linux的命令行上运行,没有 exec ;但它不会在Tcl中运行。错误为:

    Usage: "mediainfo [-Options...] FileName1 [Filename2...]"
    "mediainfo --Help" for displaying more information
    

    我读到关于“对Tcl没有特殊意义”的单引号(在 https://www.tcl.tk/man/tcl8.6/TclCmd/exec.html )那里的例子似乎用{}代替了它们。我尝试转义$,但它生成了相同的错误。

    [exec mediainfo --Output=\${General;File Name: %FileName%\nAudio;
     Duration: %Duration/String3%} 01_gen/01001.mp3]
    

    我还尝试转义分号,它不会出错,但它会返回所有值,而不仅仅是语句中请求的值。

    [exec mediainfo --Output=\${General\;File Name: %FileName%\nAudio\;
     Duration: %Duration/String3%} 01_gen/01001.mp3]
    

    我还尝试了一些扩展方法的变体,如本文所述 SO question 但我能得到的最好的结果是返回所有媒体属性,而不是请求的两个。

    set cmd {mediainfo --Output=$'General;File Name: %FileName%\nAudio;
     Duration: %Duration/String3%' 01_gen/01001.mp3}
    chan puts stdout [exec {*}$cmd]
    

    你能解释一下我做错了什么,需要做些什么才能在Tcl中执行吗?

    非常感谢。

    编辑:

    既然肖恩已经解释了这个问题,我意识到,如果我在 SO question about mediainfo 更密切地说(我对bash也不是一无所知),我本可以明确地添加新行,将这个答案称为模板;然后只使用正常的Tcl替代。有时我会很密集。

    set param {--Output=General;File Name: %FileName%
    Audio; Duration: %Duration/String3%}
    chan puts stdout [exec mediainfo $param 01_gen/01001.mp3]
    # File Name: 01001 Duration: 00:07:31.422
    
    
    1 回复  |  直到 3 年前
        1
  •  4
  •   Shawn    3 年前

    您需要:

    exec mediainfo "--Output=General;File Name: %FileName%\nAudio; Duration: %Duration/String3%" 01_gen/01001.mp3
    

    在类似shell的bash(以及其他一些,但不是POSIX-sh)中, $'...' type of quote 用于转换 \n 到一个实际的换行符,并将所有空格分隔的部分分组为一个参数;在该参数中,美元符号和单引号实际上并没有传递给程序。tcl中的双引号也有类似的效果,但应该围绕整个参数,而不仅仅是其中的一部分。