私は比較的シェルスクリプトに慣れていませんが、 lftpプログラム を使用するスクリプトをほぼ完成させました。私が問題を抱えているスクリプトの一部は、コマンドの長い文字列(;
で区切られている)を作成するときです。
for var in something
do
...
commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done
私が気づいているのは、tail
プログラム(バッククォートで囲まれている)がforループの反復時に実行されているが、スクリプトの後半でコマンドの文字列を呼び出すときに実行されていないことです。
残念ながら、$ somefileの内容は、この段階ではまだ検査する準備ができていません。文字列の作成中にではなく、必要なときにコマンドを実行するにはどうすればよいですか?
これは少しトリッキーです。 Haukeが提供した情報は正確です。それは、ユースケースのためにそれを解析するだけの問題です。
最も簡単な方法は、_$
_をエスケープしながら$()
構文を使用して、定義時に$()
で囲まれたコマンドを変数定義が実行しないようにすることです。ネストされたコマンドを実行するには、実際の実行時にシェルが最終的な結果を(eval
を介して)再評価する必要があることに注意してください。
例を見る方がはるかに簡単なので、次の例を参考にしてください。
_for((i=0;i<10;i++)); do
date +%s.%N # Print a timestamp (in format seconds.nanoseconds)
test="echo \$(date +%s.%N)" # Save a command to do the same
sleep 1 # Sleep for a second
eval "$test" # Evaluate the command saved in variable 'test'
echo # Print a new line before the next iteration
done
_
上記の例の出力例を次に示します(1回の反復にトリミングされています)。
_1398832186.133661344
1398832187.139076728
_
各ループの2番目のタイムスタンプは、最初のループの約1秒後です。逆に、test
定義の_$
_をエスケープせずにeval
を削除せずに同じテストを実行すると、2つのタイムスタンプはほぼ一致します。
ほとんどの状況でeval
を使用する習慣を身につけないでください。しかし、これは私がそれを避けるための良い方法を知らない状況の1つです。うまくいけば、これが役立ちます。幸運を!
引用にはいくつかのレベルがあります。二重引用符(_"..."
_)は、空白といくつかの特殊文字(_~
_、_&
_、_|
_、_;
_、...)を保護しますが、パラメーターの展開を妨げませんおよびコマンド置換。
単一引用符(_'
_)または「危険な」文字の前にバックスラッシュが必要です。
一般的に:バッククォートの代わりに$(tail ...)
の使用を検討する必要があります。バックティックは古い標準ですが、私たちは$()
がほとんどの人に問題を引き起こさないほど古いと言っています。新しいバージョンは読みやすく、ネストすることができます。ここでsxのフォーマットの問題は言うまでもありません...