Ame*_*ina 14 shell zsh quoting
我最近了解了watch,但在使用相对复杂的命令时遇到了麻烦。
例如,我想要求每三秒watch
运行以下命令*:zsh
for x in `command_1 | grep keyword | cut -d' ' -f1`; do command_2 "word[word=number]" $x; done
Run Code Online (Sandbox Code Playgroud)
如您所见,上面的行包括单引号、双引号和其他特殊字符。
所以我试过:
watch -n 3 "for x in `my_command | grep keyword | cut -d' ' -f1`; do command2 "rusage[mem=7000]" $x; done"
Run Code Online (Sandbox Code Playgroud)
但后来我得到了:
在 !@#$# ....; 中找不到与 x 匹配的匹配项 完毕
我尝试了其他组合但没有成功。这是其中一种尝试:
watch -n 3 "for x in $(bjobs -w | grep pre_seg | cut -d' ' -f1); do bmod -R "rusage[mem=7000]" $x; done"
Run Code Online (Sandbox Code Playgroud)
这也会导致类似的错误。
任何想法如何使这项工作?
*我也会对有效的解决方案感兴趣bash
Gil*_*il' 20
一般提示:如果您有两层嵌套,请避免在内部命令中使用单引号,并在外部命令周围使用单引号。
附加提示:不要使用反引号 - `…`
- 来执行代码,而是$(…)
在它周围使用。当涉及到嵌套引号时,美元括号几乎是 DWIM('Do what I mean');反引号具有神秘的、依赖于 shell 的规则。
watch -n 3 'for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
Run Code Online (Sandbox Code Playgroud)
如果在单引号命令中需要单引号,则可以使用'\''
. 将这四个字符视为在单引号内引用单引号的方式,尽管从技术上讲,这被构造为结束单引号字符串,附加一个文字单引号,并开始一个新的单引号字符串(仍然附加到当前词)。
对于更复杂的情况,要么煞费苦心地计算引号,要么定义临时变量。
cmd='for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
watch_cmd='watch -n 3 "$cmd"'
Run Code Online (Sandbox Code Playgroud)
此答案并非特定于 zsh。Zsh 在这里没有带来任何重要的东西。您可以节省一些引用,因为不需要在命令替换周围使用双引号,有时有一些方法可以使用内置命令而不是外部命令来减少引用需求,但底层问题与其他 shell 中的相同。
哦,顺便说一句,请注意,watch
它将在 中执行您的命令sh
,而不是在 zsh 中。如果要在zsh中执行命令,则需要运行
watch -n 3 -x zsh -c "$cmd"
Run Code Online (Sandbox Code Playgroud)
在 Debian/Ubuntu 上,以及
export cmd
watch -n 3 'exec zsh -c "$cmd"'
Run Code Online (Sandbox Code Playgroud)
(甚至更多引用!)其他地方。