1

我想在 tcl 中执行以下行:

exec awk -F"[][]" '/dB/ { print $2 }' <(amixer sget Master)

但错误:missing close-brace出现。

然后我为此更改了它:

exec awk -F"[][]" {/dB/ { print $2 }} <(amixer sget Master)

用大括号更改单引号。现在错误是:

无法读取文件"(amixer": no such file or directory

然后我改成这样:

exec awk -F{[][]} {/dB/ { print $2 }} <(amixer sget Master)

仍然与后者相同的错误。

我真的在为exec命令的 tcl 解析机制而苦苦挣扎。请帮忙。谢谢你。

amixer sget 主输出:

  Capabilities: pvolume pvolume-joined pswitch pswitch-joined
  Playback channels: Mono
  Limits: Playback 0 - 64
  Mono: Playback 39 [61%] [-25.00dB] [on]
4

2 回答 2

6

shell 和 Tcl 有完全不同的语法,这是一个重要的领域。shell调用的正确音译:

awk -F"[][]" '/dB/ { print $2 }' <(amixer sget Master)

这是:

exec amixer sget Master | awk {-F[][]} {/dB/ { print $2 }}

在partixular中,Tcl和shell对于如何引用事物以及需要引用哪些事物有着不同的想法。awk此外,仅从标准输入获取输入比尝试让 Tcl 正确处理管道以完全按照 shell 正在执行的方式进行重定向要容易得多(你可以做到,但这是一项艰苦的工作,真的不值得费心对于这么简单的事情)。

当然,您可以改用 Tcl 进行解析,因为它具有合理的正则表达式匹配支持。例如,这将分贝级别存储在变量中decibels

set mixer "Master"
regexp {\[([\d.]+)dB\]} [exec amixer sget $mixer] -> decibels
于 2013-09-06T12:31:03.917 回答
0

感谢 Donal Felows 我发现问题在于shell 引用 ,而在于tcl 语法。所以我修改了我的整个答案以提出以下建议:

exec /bin/bash -c {amixer sget Master | awk -F"[][]" '/dB/{print $2}'}

或者如果您喜欢使用进程替换而不是管道:

exec /bin/bash -c {awk -F"[][]" '/dB/{print $2}' <(amixer sget Master)}

这两行都使用{...}语法将bash代码从tcl解释中转义,从而允许bash介于两者之间的正常代码。

我不确定这是否是最好的方法,因为它基本上将所有工作从 转移tclbash,但至少这对我有用(使用tcl8.5.13-r1、GNU bash4.2.45(1) 和 GNU awk4.0 .1)。

于 2013-09-06T08:10:54.093 回答