背景

背景

背景

複数のホストのプロセスを表示するコマンドを実行しています。コマンドは次のとおりです。

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引数を実行するには一重引用符が必要です。 [...]

まさか。引用符は単にシェル構造にすぎず、シェルにドル記号を拡張するのではなく、文字列をスペースで除算する代わりにフラグメントとして保持するように指示します。 awkが見るものはすべて文字列であり{print $2}、それがどのように生成されたのかわかりません。二重引用符とバックスラッシュエスケープを使用して同じ効果を得ることができます。以下はすべて同じでなければなりません。

awk '{print $2}'
awk "{print \$2}"
awk {print\ \$2}

後者の2つは、問題なく一重引用符で囲まれた文字列に入れることができます。

または、シェルがBashまたはANSI C引用符をサポートする他のシェルの場合は、$'..'外部引用符をに変更して$'..'からバックスラッシュを使用して単一引用符をエスケープすることもできます。

echo $'do or don\'t'

名前が示すように、他のCスタイルエスケープ(たとえば\n、、、、、、など)も機能します。\t\"\'\\$'..'

答え2

awk自体には一重引用符が「必要」ではありません。スクリプトの本文に含める内容が含まれていることを確認するだけです。次をエスケープすると、二重引用符が表示されます$

execAll ... '...; ipcs | awk "/666/ {print \$2}" | xargs ...'

関連情報