私は最近学んだよりしかし、比較的複雑なコマンドを使用して動作するのに苦労しました。
watch
たとえば、次のコマンドが3秒ごとに実行されるようにしたいと思います*: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
答え1
一般的なヒント: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
zshからコマンドを実行することに注意してくださいsh
。 zsh でコマンドを実行するには、以下を実行する必要があります。
watch -n 3 -x zsh -c "$cmd"
Debian / Ubuntuで、そして
export cmd
watch -n 3 'exec zsh -c "$cmd"'
(もっと引用してください!)他の場所。