2012-12-08 20 views
23

Tôi có những điều sau đây trong một Makefile cho mục đích tái tạo cơ sở dữ liệu của tôi bao gồm phá hủy nó nếu cần thiết. Nó không hoạt động.Làm cách nào để sử dụng các biến shell trong các hành động 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 

Chạy nó kết quả trong một lỗi:

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

Tại sao điều này xảy ra? Nó trông giống như Bash hợp lệ theo như tôi có thể nói? Có những cân nhắc đặc biệt tôi phải thực hiện khi thực hiện điều này trong Makefile không?

UPDATE:

Sử dụng câu trả lời tôi đến một phiên bản làm việc:

.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 

Trả lời

38

Có ít nhất hai cân nhắc. $() tham chiếu biến Biến. Bạn phải thoát khỏi số $ để thực hiện lệnh thay thế. Ngoài ra, các lệnh shell phải là tất cả trên một dòng. Hãy thử:

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 

Mặt khác, nó có vẻ như nó sẽ đơn giản hơn chỉ cần luôn luôn cố gắng để thả các cơ sở dữ liệu, và cho phép thất bại: hơn

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

Có một vài sắc thái về "tất cả trên một dòng "có giá trị thảo luận: (truyền thống và portably) tất cả mọi thứ mà bạn muốn được thực hiện bởi ** cùng một vỏ ** phải trên một dòng _make_ hợp lý. Vì vậy, 'exist = ...' và 'if ... fi' phải được tạo thành một dòng lệnh duy nhất với dấu chấm phẩy và dấu gạch chéo ngược, nhưng' createdb ... 'có thể vẫn là một lệnh thứ hai riêng biệt trong công thức. –

+1

Để người đọc: Hãy chắc chắn rằng bạn đặt '\' ở cuối câu lệnh 'VAR =" foo "\' – redolent

+1

"Tất cả trong một dòng" có thể được thư giãn bằng cách sử dụng '.ONESHELL:' như được mô tả trong https: //www.gnu.org/software/make/manual/html_node/One-Shell.html#One-Shell – sdive

Các vấn đề liên quan