bash
  • makefile
  • 2012-12-08 2 views 23 likes 
    23

    私は必要に応じてデータベースを破壊することを含め、自分のデータベースを再作成する目的でMakefileに次のものを持っています。それは動作しません。Makefileアクションでシェル変数を使用するにはどうすればよいですか?

    .PHONY: rebuilddb 
        exists=$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'") 
        if [ $(exists) -eq 1 ]; then 
         dropdb the_db 
        fi 
        createdb -E UTF8 the_db 
    

    実行するには、エラーが発生:

    $ make rebuilddb 
    exists= 
    if [ -eq 1 ]; then 
    /bin/sh: -c: line 1: syntax error: unexpected end of file 
    make: *** [rebuilddb_postgres] Error 2 
    

    なぜこれが間違っていますか?私が知る限り、有効なBashのように見えますか? Makefileでこれを行う際に特別な考慮事項がありますか?私は作業バージョンに到着した答え使用

    UPDATE

    .PHONY: rebuilddb 
        exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'"); \ 
        if [ "$$exists" == "1" ]; then \ 
         dropdb the_db; \ 
        fi; 
        createdb -E UTF8 the_db 
    

    答えて

    38

    は、少なくとも二つの考慮事項があります。 $()はMake変数を参照します。コマンド置換を行うには、$からエスケープする必要があります。また、シェルコマンドはすべて1行に記述する必要があります。試してみてください。一方

    exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM \ 
        pg_database WHERE datname='the_db'"); \ 
        if [ "$$exists" -eq 1 ]; then \ 
         dropdb the_db; \ 
        fi; \ 
        createdb -E UTF8 the_db 
    

    をそれだけで、常にデータベースを削除しようとすると、失敗を許可するように簡単になるように、それはそう:

    rebuilddb: 
        -dropdb the_db # Leading - instructs make to not abort on error 
        createdb -E UTF8 the_db 
    
    +3

    すべての」についてさらにいくつかのニュアンスがあります。あなたは**同じシェル**によって実行されたいものはすべて、一つの論理_make_行になければなりません。 'exists = ...'と 'if ... fi'はセミコロンとバックスラッシュで1つのコマンドラインにする必要がありますが、' createdb ... 'はレシピの別の2番目のコマンドとして幸せに残ります。 –

    +1

    読者に:あなたの 'VAR =" foo "\'ステートメントの末尾に '\'を入れてください。 – redolent

    +1

    https:で説明されているように、 '.ONESHELL:'を使って "all in one line" //www.gnu.org/software/make/manual/html_node/One-Shell.html#One-Shell – sdive

    関連する問題