別のコマンドの単一引用符と二重引用符を含むコマンドをラップする


10

最近watchについて学びました、比較的高度なコマンドで動作させるのに苦労しています。

たとえば、3秒ごとにwatch次のコマンドを実行するように依頼します*zsh

for x in `command_1 | grep keyword | cut -d' ' -f1`; do command_2 "word[word=number]" $x; done

上記の行を見るとわかるように、他の特殊文字の中に、単一引用符、二重引用符が含まれています。

だから私は試しました:

watch -n 3 "for x in `my_command | grep keyword | cut -d' ' -f1`; do command2 "rusage[mem=7000]" $x; done"

しかし、私は得ました:

!@#$#....;でxに一致するものが見つかりませんでした。終わった

他の組み合わせを試したが成功しなかった。これらの試みの1つを次に示します。

watch -n 3 "for x in $(bjobs -w | grep pre_seg | cut -d' ' -f1); do bmod -R "rusage[mem=7000]" $x; done"

これも同様のエラーになります。

これを機能させる方法はありますか?


*私も動作するソリューションに興味がありますbash

回答:


16

一般的なヒント:2レベルのネストがある場合は、内側のコマンドで単一引用符を使用しないでください。外側のコマンドは単一引用符で囲んでください。

追加のヒント:バッククォートを使用しない`…` --コードを実行する代わりに、コードの$(…)周りを使用します。ドル括弧は、ネストされた引用符に関しては、ほとんどDWIM(「どういう意味か」)です。バッククォートには難解なシェル依存のルールがあります。

watch -n 3 'for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'

単一引用符で囲まれたコマンド内で単一引用符が必要な場合は、を使用できます'\''。これらの4つの文字は、一重引用符内で一重引用符を引用する方法と考えてください。ただし、技術的には、これは一重引用符で囲まれた文字列を終了し、リテラル一重引用符を追加し、新しい一重引用符で囲まれた文字列を開始します(引き続き現在の単語)。

より複雑なケースでは、引用符を慎重にカウントするか、一時変数を定義します。

cmd='for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
watch_cmd='watch -n 3 "$cmd"'

この回答はzshに固有のものではありません。Zshはここで重要なことは何もしません。コマンド置換を二重引用符で囲む必要がないため、引用符を少し節約できます。また、引用符の必要性を減らす外部コマンドではなく組み込みコマンドを使用する方法がある場合もありますが、根本的な問題は他のシェルと同じです。

ああ、ところで、zshではなくでwatchコマンドが実行されることに注意してくださいsh。zshでコマンドを実行する場合は、次を実行する必要があります

watch -n 3 -x zsh -c "$cmd"

Debian / Ubuntu、および

export cmd
watch -n 3 'exec zsh -c "$cmd"'

(さらに引用!)他の場所。


@Gillesに感謝します。それはとても役に立ちました。興味深いことに、私のマシンにはのオプションもwatch付属していません。私はそれをオンラインで調べましたが、それらについて言及しているマニュアルページは見つかりませんでした。これらのオプションは何をしますか?-x-c
Amelio Vazquez-Reina、

1
@intrpc -xwatch、シェルを介してコマンドを渡さないように指示します。そのように示されていなくても、これはDebian / Ubuntuに固有であることがわかりました。-c渡されzshないように、watch
Gilles「SO-悪をやめる」

@Gilles -x-execオプションは両方ともwatch(gentooで)私に存在するので、これは間違いなくDebian固有のものではありません。多分あなたは他のいくつかのバージョンと比較しましたかwatch?鉱山はprocpsパッケージから来ています。
rozcietrzewiacz 2011年

1
@rozcietrzewiacz もDebian watchからのものprocpsです。公式のソースはありません--exec。Debian(およびUbuntuを含む派生物)のパッケージは、Debian固有のパッチ(watch_exec_beep.patch; バグ#410967の「Mortys watch execパッチ」)にオプションを追加します。Gentooも同様のパッチを採用している可能性があります。
Gilles「SO-悪をやめる」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.