2012-01-08 46 views
6

Điều này tương tự như another issue, nhưng tôi chỉ muốn make để nhắc giá trị nếu tôi đang chạy một mục tiêu cụ thể cụ thể và biến bắt buộc chưa được chỉ định.Làm thế nào để nhắc cho biến Makefile mục tiêu cụ thể nếu không xác định?

Mã hiện tại:

install-crontab: PASSWORD ?= "$(shell read -p "Password: "; echo "$$REPLY")" 
install-crontab: $(SCRIPT_PATH) 
    @echo "@midnight \"$(SCRIPT_PATH)\" [...] \"$(PASSWORD)\"" 

này chỉ dẫn đến đầu ra sau và không có dấu nhắc:

Password: read: 1: arg count 
@midnight [...] "" 

Điểm quan trọng ở đây là tôi phải hỏi chỉ khi chạy này mục tiêu và chỉ nếu biến chưa được xác định. Tôi không thể sử dụng tập lệnh configure, vì rõ ràng tôi không nên lưu trữ mật khẩu trong tập lệnh cấu hình và vì mục tiêu này không phải là một phần của quy trình cài đặt chuẩn.

Trả lời

6

Tắt vấn đề là Makefiles không sử dụng dấu ngoặc kép kiểu Dash/Bash, mà tên của Dash là read cần có tên biến, không giống như Bash. mã kết quả:

install-crontab-delicious: $(DELICIOUS_TARGET_PATH) 
    @while [ -z "$$DELICIOUS_USER" ]; do \ 
     read -r -p "Delicious user name: " DELICIOUS_USER;\ 
    done && \ 
    while [ -z "$$DELICIOUS_PASSWORD" ]; do \ 
     read -r -p "Delicious password: " DELICIOUS_PASSWORD; \ 
    done && \ 
    while [ -z "$$DELICIOUS_PATH" ]; do \ 
     read -r -p "Delicious backup path: " DELICIOUS_PATH; \ 
    done && \ 
    (\ 
     CRONTAB_NOHEADER=Y crontab -l || true; \ 
     printf '%s' \ 
      '@midnight ' \ 
      '"$(DELICIOUS_TARGET_PATH)" ' \ 
      "\"$$DELICIOUS_USER\" " \ 
      "\"$$DELICIOUS_PASSWORD\" " \ 
      "\"$$DELICIOUS_PATH\""; \ 
     printf '\n') | crontab - 

Kết quả:

$ crontab -r; make install-crontab-delicious && crontab -l 
Delicious user name: a\b c\d 
Delicious password: e f g 
Delicious backup path: h\ i 
no crontab for <user> 
@midnight "/usr/local/bin/export_Delicious" "a\b c\d" "e f g" "h\ i" 
$ DELICIOUS_PASSWORD=foo make install-crontab-delicious && crontab -l 
Delicious user name: bar 
Delicious backup path: baz 
@midnight "/usr/local/bin/export_Delicious" "a\b c\d" "e f g" "h\ i" 
@midnight "/usr/local/bin/export_Delicious" "bar" "foo" "baz" 

Mã này:

  • xử lý tất cả các ký tự đầu vào như literals, vì vậy nó hoạt động với không gian và gạch chéo ngược,
  • tránh vấn đề nếu người dùng nhấn Nhập mà không cần viết bất cứ điều gì,
  • sử dụng biến môi trường nếu chúng tồn tại và
  • hoạt động cho dù crontab có trống hay không. Câu hỏi của
2

l0b0 đã giúp tôi giải quyết vấn đề tương tự nơi tôi muốn thoát nếu người dùng không nhập 'y'. Tôi đã kết thúc việc này:

@while [ -z "$$CONTINUE" ]; do \ 
    read -r -p "Type anything but Y or y to exit. [y/N] " CONTINUE; \ 
done ; \ 
if [ ! $$CONTINUE == "y" ]; then \ 
if [ ! $$CONTINUE == "Y" ]; then \ 
    echo "Exiting." ; exit 1 ; \ 
fi \ 
fi 

Tôi hy vọng sẽ giúp ai đó. Thật khó để tìm thêm thông tin về cách sử dụng đầu vào của người dùng cho if/else trong một makefile.

+0

Trừ khi mắt tôi đánh lừa tôi, trong khi vòng lặp sẽ lặp lại thay vì sử dụng mặc định 'N' nếu bạn chỉ cần nhấn Enter. – l0b0

+0

Bạn nên sử dụng một [dấu bằng đơn trong '['] (http://mywiki.wooledge.org/Bashism#Conditionals) – l0b0

+2

Bạn cũng có thể đơn giản hóa câu lệnh 'if':' if [$$ CONTINUE! = "Y "] && [$$ CONTINUE! =" Y "]; sau đó'. Hoặc thậm chí '[$$ CONTINUE =" y "] || [$$ CONTINUE = "Y"] || (echo "Thoát".; thoát 1;) ' – l0b0

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