2009-07-13 6 views
1

私は別のファイルの内容をソースとするbashスクリプトを持っています。他のファイルの内容は、実行して戻り値を比較するコマンドです。コマンドの中には、複数のコマンドがセミコロン(;)またはアンパサンド(& &)で区切られているものがありますが、これを行うことはできません。示すように、この上で動作するように、私はいくつかのテストスクリプトを作成しました:複数のコマンドとリエントラントがある変数

Test.confをテスト

例-1(これは動作します)によって供給されているファイルで、私の出力は違い

で2秒ですTest.confを

 
    CMD[1]="date" 

test.sh

 
    . test.conf 
    i=2 
    echo "$(${CMD[$i]})" 
    sleep 2 
    echo "$(${CMD[$i]})" 

例-2(これが機能しません) Test.confを(上記と同じスクリプト)

 
    CMD[1]="date;date" 

例-3(この試み、それがいずれかの動作しない) Test.confを(上記と同じスクリプト)

 
    CMD[1]="date && date" 

I「はドン私の変数CMDを目盛りにしたいのは、ソースの呼び出し時にコマンドが実行され、変数を再評価する方法がないからです。

このスクリプトは、パス1の場合に何かをチェックするために、パス1で本質的にCMDを呼び出します。私は誤読を取得しますが、誤読を修正して再実行するスクリプトで作業します。&出力を再評価します。 CMDのパス2。

ここは例です。ここではSSHDが動作しているかどうか確認しています。私がパス1でCMD [1]を評価するときに実行されていない場合、私はそれを開始し、CMD [1]を再度評価します。私は私のテストスクリプトのためにこれを変更した場合

Test.confを

 
    CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?` 

だから、その後、Test.confをは次のようになります。 注:マークが表示されないが、それは私のキーボード上〜マーク下のキーだダニ。

 
    CMD[1]=`date;date` or `date && date` 

私のスクリプトは、私が2秒の遅延にもかかわらず、二度印刷された同じ日付/時刻を取得

 
    . test.conf 
    i=2 
    echo "${CMD[$i]}" 
    sleep 2 
    echo "${CMD[$i]}" 

(目盛りを処理するために)このようになります。したがって、CMDは再評価されていません。

+1

あなたの質問は明確ではない - 実際に、私は質問が表示されません。あなたは何をしようとしていますか、それはどこが間違っていますか?あなたの "example"、 "test.conf CMD [1] = pgrep -u" ...は "ソースファイル"はどこですか?あなたはどのように議論を解析していますか?私はそれを見ていますか? –

+0

これはテストスクリプトであり、実際のものではありません。それで、$ iがまだそこにある(カット・アンド・パース)理由は明瞭ではありません。 CMD [x](x = 0 ... 10)は、1または0のいずれかを返すテスト条件です。ほとんどの場合、上記のpgrepの例と同じかどうかは分かりません。 CMDに加えて、対応するRESTART [x]があり、コールした後、CMD [x]を再評価して、プロセスが再開したかどうかを確認します。他の例では、ログファイルの存在を確認しています。私はこれらの詳細を持つフォーラムを退屈したくはありませんでしたが、おそらく役に立ちましたでしょう。 ありがとうございました! – Eric

答えて

1

まず古いシェルと互換性がある必要がある場合を除き、あなたは、バッククォートを使用しないでください$() - をサポートしていない場合はです。あなたがCMD[1]を設定するが、その後2iセットでCMD[$i]を呼んでいる理由

第二に、私は理解していません。

とにかく、これは一つの方法である(そしてそれはバリーの答えの一部に似ています):

CMD[1]='$(date;date)' # no backticks (remember - they carry Lime disease) 
eval echo "${CMD[1]}" # or $i instead of 1 
+0

これも機能します。私はこの方法を考えていませんでした。優れたありがとう! – Eric

1

あなたの質問の行のカップルから、私はこのようないくつかのアプローチが期待しているでしょう:あなたがソースにバッククォートを持っている場合は、あなたがあまりにも早くそれを評価避けるために、それらをエスケープする必要があります

#!/bin/bash 

while read -r line; do 
    # munge $line 
    if eval "$line"; then 
     # success 
    else 
     # fail 
    fi 
done 

を。また、コードを評価する唯一の方法はバックティックではありません。上記のようにevalがあります。多分それはあなたが探していたevalですか?

たとえば、次の行:

CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?` 

は、おそらくより次のようになり退くべき:すべての

CMD[1]='`pgrep -u root -d , sshd 1>/dev/null; echo $?`' 
+0

これは機能します!しかし、私とあなたの以前のコメント(私たちは同意する)ごとに私はそこにダニを望んでいない。このスクリプトは、Linux以外の環境には存在しません。私はBASHを制御することはできず、移植性に関する懸念に同意します。 – Eric

関連する問題