コマンドに-loopを使用できますかfor
?watch
私の試みでこのエラーを解決する方法がわかりません。
$ for i in 1 2 3; do echo $i; done
1
2
3
$ watch -n 10 for i in 1 2 3; do echo $i; done
-bash: syntax error near unexpected token `do'
$ watch for i in 1 2 3; do echo $i; done
-bash: syntax error near unexpected token `do'
$
答え1
watch
~の注文するパラメータはスクリプトの実行に使用されますsh -c
。
もし注文する引数はスペースで区切られたトークンのリスト(例watch ls -l
)にすぎず、すべてのトークンを連結して実行します。ただし、引用されていないシェルメタ文字は次のとおりです。watch
実行するシェルで使用そして見たことがないwatch
。
;
&
|
<
>
これは、実行中のシェルがwatch
これらのwatch
文字をコマンドの終わりを表示したり、バックグラウンドでwatchコマンドを実行したり、出力をwatch
別のプログラムにパイプするコマンドとして解釈したりするのを防ぐために、エスケープや引用などのメタ文字をエスケープまたは引用する必要があることを意味します。 (パイプラインを実行する監視スクリプト内を除く)
一般的な引用規則を適用します。変数の補間を防ぐには一重引用符を使用し、それ以外の場合は二重引用符を使用します。 man watch
最後の部分にこれを示すサンプルセクションがあります。
たとえば、
watch -n 10 'for i in 1 2 3; do echo $i; done'
または
watch -n 10 'grep something /var/log/kern.log | tail'
注:.egなしで実行したい場合watch
。-x
sh -c
watch -x awk -f script.awk
答え2
入力したコマンドは、シェルが実行を試みる前に現在のシェルによって解析されますwatch
。シェルはこれを説明します;
。do
なぜなら、シェルからこのアイテムを保護するために何もしなかったからです。予期しないことですが、最初からdo
シェルがそれをコマンドターミネータとして解釈したくありません。;
通常、エスケープ(例\;
:)または引用符(例:)を使用して、シェルから';'
コンテンツが解釈/拡張されないように保護できます。あなたの場合は、;
およびを保護する必要があります$
。しかし、質問があります。何をwatch
すべきか?
通常watch
、コマンドを実行する以上のものです。つまり、いくつかのコードをに渡しますsh -c
。コードは1つ以上の引数に基づいて書かれていますwatch
(例:watch echo foo
のように動作しますwatch "echo foo"
)。
watch -x
シェルなしでコマンドを実行できますが、for
ループを実行するにはシェルが必要です。
実際には、watch
複数の引数でシェルコードを記述すると、複数のスペースが重要であり、誤って引用したときにエラーが発生する可能性があります。同様のタスクを実行する別のコマンドはssh
次のとおりです。私の答え。
これらすべての問題を解決する1つの方法は、単一引用符を使用することです。すべてあなたはそれがシェルコードになりたいですwatch
。まさに一つコードのパラメータを含みます。あなたの場合:
watch -n 10 'for i in 1 2 3; do echo $i; done'
通常、コードはwatch
実行時にsh
自己引用符を必要とし、時には単一引用符を必要とします。そこしたがって、コード全体を新しい一重引用符で囲むだけで動作することも、動作しないこともあります。新しい一重引用符が現在のシェルのコンテキストにすでに存在する一重引用符と対になっている場合は機能しません(または最良の場合は偶然に機能します)。よりBashで一重引用符を使いやすくするか、コマンドライン全体をエスケープする方法は?。リンクされた質問には、一般的な手動ソリューションが含まれています。私の答えは、Bashでこれらの参照を自動化する方法を提供します。