2012-01-08 9 views
6

Questo è simile a another issue, ma voglio solo make per richiedere un valore se sto utilizzando un target specifico e una variabile obbligatoria non è stata specificata.Come richiedere la variabile Makefile specifica della destinazione se non definita?

Il codice corrente:

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

Ciò si traduce solo nel seguente output e nessuna richiesta:

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

Il punto importante qui è che devo chiedere solo quando si esegue questo target e solo se la variabile non è stata definita. Non riesco a utilizzare uno script configure, perché ovviamente non dovrei memorizzare le password in uno script di configurazione e poiché questa destinazione non fa parte della procedura di installazione standard.

risposta

6

scopre che il problema era che non usano Makefiles citazione Dash/Bash-stile, e che di Dash read built-in ha bisogno di un nome di variabile, a differenza di Bash. codice risultante:

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 - 

Risultato:

$ 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" 

Questo codice:

  • tratta tutti i caratteri di input come letterali, quindi funziona con spazi e backslash,
  • evita i problemi se il utente preme Immettere senza scrivere nulla,
  • utilizza le variabili di ambiente se esistono e
  • funziona se crontab è vuoto o meno.
2

La risposta di l0b0 mi ha aiutato con un problema simile in cui volevo uscire se l'utente non inseriva "y". Ho finito per fare questo:

@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 

Mi auguro che aiuta qualcuno. È difficile trovare più informazioni sull'utilizzo dell'input dell'utente per un if/else in un makefile.

+0

A meno che i miei occhi non mi ingannino, quel ciclo si ripeterà piuttosto che usare il 'N' predefinito se semplicemente premi Invio. – l0b0

+0

Dovresti usare un [singolo segno uguale in '['] (http://mywiki.wooledge.org/Bashism#Conditionals) – l0b0

+2

Puoi anche semplificare l'istruzione 'if':' if [$$ CONTINUE! = "Y "] && [$$ CONTINUE! =" Y "]; then'. O anche '[$$ CONTINUE =" y "] || [$$ CONTINUE = "Y"] || (echo "Exiting."; exit 1;) ' – l0b0

Problemi correlati