4

作業中のリポジトリ内で単純な bash スクリプトを実行するために使用するメイクファイルがあります。mySQL データベースに自動的にログインする新しい make 呼び出しを試みています。ユーザー名とパスワードを既知の場所 ("/u/r/z/myid/.zinfo" など) の .zinfo ファイルに保存しています。このファイルの行を読み取って、次の形式のパスワードを取得しようとしています。

user = csj483
database = cs495z_csj483
password = fjlID9dD923

これは、メイクファイルから実行しようとしているコードですが、機能していません。シェルで同じコードを直接実行すると、問題なく動作するようです。make は単一の $$ を好まないため、二重の $$ を使用する必要があったことに注意してください。

login:
    for line in $$(cat /u/z/users/cs327e/$$USER/.zinfo); \
    do \
        PASSWORD=$$line; \
        echo $$PASSWORD; \
    done 
    echo $$PASSWORD

この時点で、パスワードを取得しようとしています。これは、ループで PASSWORD が設定される最後の値である必要があります。誰かがパスワードを取得する簡単な方法を提案したり、コードのエラーを指摘したりできる場合は、感謝します。最終的には、データベース名も取得したいと思います。それについても助けていただければ幸いです。私は bash は初めてですが、他の多くの言語の経験があります。

4

1 に答える 1

14

「機能しない」とはどういう意味かを指定しませんでした。質問をするときは、入力したコマンド、得られた結果 (カット アンド ペーストが最適です)、およびそれが期待したものではない理由について常に明確にしてください。

いずれにしても、最初のエコーでは期待どおりの出力が表示されるのに、2 番目のエコーでは表示されないという動作が見られる可能性が最も高いです。これは、レシピ内の各論理行を別のシェルmakeで呼び出すためです。そのため、for ループは 1 つのシェルで実行され、環境変数 が設定されます。その後、そのシェルが終了し、最後のシェルが新しいシェルで実行されます... が設定されなくなりました。PASSWORDechoPASSWORD

コマンドライン全体をレシピ内の 1 つの論理行に入れる必要があります。

login:
         for line in $$(cat /u/z/users/cs327e/$$USER/.zinfo); do \
             PASSWORD=$$line; \
             echo $$PASSWORD; \
         done \
         && echo $$PASSWORD

最後に 1 つ覚えておくべきことがあります。あなたは bash スクリプトを実行していると言いましたが、make は bash を実行しませ。個人的に使用しているシェルに関係なく、実行され/bin/shます (メイクファイルがユーザーがたまたま使用していたシェルを使用した場合の大混乱を想像してください!)。最良の選択肢は、ポータブル シェル構文でレシピを記述することです。本当にそれができない場合は、強制的に make に bash を使用するように設定SHELL := /bin/bashしてください。Makefile

到着予定時刻:

より大きな質問に関しては、多くのオプションがあります。zinfo ファイルのフォーマットを制御できる場合は、シェルと同じ構文を使用して変数を定義するように定義することをお勧めします。=上記の例で、次のように記号の周りの空白を削除した場合:

user=csj483
database=cs495z_csj483
password=fjlID9dD923

次に、変数が割り当てられた有効なシェル スクリプトを作成します。これで、makefile でこのスクリプトを source できるようになり、作業は非常に簡単になりました。

login:
        . /u/z/users/cs327e/$$USER/.zinfo \
            && echo user is $$user \
            && echo database is $$database \
            && echo password is $$password

zinfo ファイルの構文を制御できない場合、生活はより困難になります。次のような eval を使用できます。

login:
        while read var eq value; do \
            eval $$var="$$value"; \
        done < /u/z/users/cs327e/$$USER/.zinfo \
            && echo user is $$user \
            && echo database is $$database \
            && echo password is $$password

このバージョンは、「=」の周りにスペースがある場合にのみ機能します。両方をサポートしたい場合は、それも可能です。

于 2013-04-19T19:39:29.053 に答える