背景
我正在运行一个显示多个主机上进程的命令。下面是命令:
execAll -m "$HOSTS" 'hostname; ps -ef | grep build | grep -v grep; ipcs | grep 666'
试图
我现在想将ipcs | grep 666
命令的一部分通过管道传输到awk '{print $2}'
,然后通过管道传输到kill -9
以终止所有活动进程。以下是我尝试过的:
execAll -m "$HOSTS" 'hostname; ps -ef | grep build | grep -v grep; ipcs | grep 666 | awk '{print $2}' | xargs kill -9'
但是,awk
需要单引号来运行其参数,并且上面的命令也需要单引号。我得到的错误是Missing }.
,我将其归因于上面的引用问题。
问题
在上述情况下如何成功运行awk
并杀死进程?
答案1
但是,
awk
需要单引号来运行其参数,[...]
并不真地。引号只是一个 shell 构造,它们告诉 shell 不要展开美元符号并将字符串保持为一个片段,而不是在空格上将其打断。 awk 看到的只是字符串{print $2}
,它不知道它是如何生成的。您可以使用双引号和反斜杠转义达到相同的效果。所有这些都应该是相同的:
awk '{print $2}'
awk "{print \$2}"
awk {print\ \$2}
后两者可以毫无问题地放入单引号字符串中。
或者,如果您的 shell 是 Bash 或其他支持 ANSI C 引用的 shell,$'..'
则可以将外部引号更改为$'..'
,然后也用反斜杠转义单引号:
echo $'do or don\'t'
顾名思义,其他 C 风格转义符(例如\n
, \t
, \"
, \'
, \\
)也可以在其中工作$'..'
。
答案2
awk 本身并不“需要”单引号。您只需要确保脚本主体包含您希望它包含的内容。如果您转义以下内容,则会找到双引号$
:
execAll ... '...; ipcs | awk "/666/ {print \$2}" | xargs ...'