文字列の Bash コマンドは、後で使用するのではなく、文字列を作成するときに実行されます。

文字列の Bash コマンドは、後で使用するのではなく、文字列を作成するときに実行されます。

私はシェルスクリプトに初めて触れましたが、エクスプロイトをほぼ完了しました。FTPプログラム。スクリプトで問題があるのは、長いコマンドのリスト(で区切り;)を生成するときです。

for var in something
do
    ...
    commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done

私が気づいたのは、tailスクリプトで後でコマンド文字列を呼び出すのではなく、forループが繰り返されるとプログラム(バックティックで囲まれた)が実行されることです。

残念ながら、このステップでは $somefile の内容を調べる準備ができていません。文字列が生成されるのではなく、必要なときにコマンドが実行されるようにするにはどうすればよいですか?

ベストアンサー1

これは少しトリッキーです。 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タイムスタンプがほぼ一致します。

ほとんどの状況でそれを使用する習慣を持ち上げないでくださいeval。しかし、これは避ける良い方法を知らない状況の1つです。お役に立てば幸いです。頑張ってください!

おすすめ記事