Configurazione utente di uno script di shell. Migliori pratiche?


13

Sto scrivendo uno script di shell con alcune variabili che dovrebbero essere configurate dall'utente. Ci sarà un programma di installazione per il download e la configurazione dello script, eventualmente ponendo una serie di domande. Lo script in questione è rivolto ad altri sviluppatori.

Questo può essere implementato in diversi modi:

  1. Usa i segnaposto nello script stesso e utilizzali sedper sostituirli durante l'installazione (qualcosa del genere: /programming/415677/how-to-replace-placeholders-in-a-text-file )

    • Pro: tutte le definizioni delle variabili sono contenute nello script. È facile scaricare manualmente lo script e configurare le variabili per gli utenti che preferiscono un editor rispetto al programma di installazione.

    • Contro: è difficile riconfigurare le variabili attraverso il programma di installazione una volta che sono in atto. A meno che non crei una regexp più complessa che sarebbe soggetta a errori.

  2. Usa un file di configurazione , in pratica un altro script di shell con assegnazioni, e usa sourceper includerlo. (E probabilmente inserirlo in ~/.scriptname? Lo script principale viene copiato in /usr/local/bin)

    • Pro: è facile riconfigurare lo script. Potrebbe anche aggiungere un parametro per farlo dallo script principale (probabilmente funzionerebbe anche nella prima soluzione, ma modificare uno script da solo non sembra un'ottima idea)

    • Contro: lo script ora dipende da due file e l'utente deve eseguire il programma di installazione per creare il file di configurazione. Questo può essere risolto generando automaticamente un file di configurazione se non esiste. Ma individuare un file di configurazione esterno sarà ancora più complicato per gli utenti che desiderano semplicemente scaricare lo script, modificarlo e completarlo.

Inoltre, alcune opzioni su come la configurazione deve essere gestita dall'utente dopo l'installazione:

  1. Come
    $ myscript config server.host example.org $ myscript config server.proxypath / home / johndoe / proxy $ myscript config server.httppath / home / johndoe / web

  2. Interactive
    $ myscript config
    Immettere il nome host del server: esempio.org
    Immettere il percorso del proxy sul server: / home / johndoe / proxy
    Immettere il percorso della directory http sul server: / home / johndoe / web

  3. getopts con opzioni lunghe
    $ myscript --host example.org --proxypath / home / johndoe / proxy --httppath / home / johndoe / web

  4. Semplice
    $ myscript config example.org / home / johndoe / proxy / home / johndoe / web

Ci sono altri modi per farlo che potresti prendere in considerazione?
Qualche best practice, qualcosa di elegante?


2
Non dubito che tu possa scrivere uno script di shell che fa tutto questo, ma la domanda è perché vuoi scrivere qualcosa di così complesso in quanto richiede un programma di installazione in uno script di shell. Comunque, guarda come il sistema di configurazione del kernel Linux gestisce il suo file di configurazione.

Bene. Lo script 'installer' scarica solo lo script reale, lo copia nella posizione corretta e pone una serie di domande per la configurazione (3-4 variabili). In questo modo posso dare agli utenti una singola riga di comando, wgetting lo script di installazione e reindirizzarlo a / bin / sh. Naturalmente potrei saltare il programma di installazione e aggiungere semplicemente un parametro 'install' allo script principale. Forse una soluzione migliore, cosa ne pensi?
Charlie Rudenstål,

"ma la domanda è: perché vuoi scrivere qualcosa di così complesso", ecco lo script in questione: github.com/charlie-rudenstal/depo Sto cercando di ridurre la quantità di passaggi necessari ai nuovi utenti, soprattutto durante installazione. Cercare di rendere automatica anche la configurazione del server richiesta.
Charlie Rudenstål,

Risposte:


6

Cosa mi aspetterei da un programma sano (uno script di shell o no):

  • Non ho mai dovuto modificare l'eseguibile per configurarlo. Questo non è un kernel del sistema operativo.
  • Posso passare qualsiasi impostazione utilizzando la riga di comando. Questo è un must per ogni informazione che non ha un default ragionevole. L'unica eccezione è una password che necessita di input interattivi.
  • Facoltativamente, posso passare un'impostazione utilizzando una variabile di ambiente.
  • Posso scrivere le impostazioni in un file di configurazione e questo file verrà utilizzato se è presente con un nome noto o se viene esplicitamente indicato l'utilizzo dei due metodi sopra.
  • Il file di configurazione utilizza gli stessi nomi di impostazione e sintassi della riga di comando.

Ottimo consiglio Questo sarebbe il tuo ordine preferito? (1) Controlla le impostazioni passate nella riga di comando (2) Controlla l'impostazione in un .scriptnameConfig nella stessa directory (3) Controlla l'impostazione in una variabile d'ambiente (4) Controlla l'impostazione in un .scriptnameConfig in ~ / .scriptnameConfig (5) Usa impostazione predefinita ambientazione
Charlie Rudenstål,

"Il file di configurazione utilizza gli stessi nomi di impostazione e sintassi della riga di comando." - Come dovrebbe essere? Stavo per usare la sintassi dell'assegnazione per i normali script di shell: SETTING = VALUE. Il comando come la sintassi non sarebbe un po 'strano in un file di configurazione?
Charlie Rudenstål,

Scopri come mounto sshti consente di utilizzare la stessa sintassi nella riga di comando e in config. Non è necessario copiare totalmente la sintassi della riga di comando; invece di '--foo = bar' puoi usare 'foo = bar'. Se invece si utilizzasse "BarOption: Foo", sarebbe molto meno conveniente: la necessità di ricordare se il caso è significativo, quale parola chiave è accettata nel file e quale sulla riga di comando e l'impossibilità di copiare e incollare un comando funzionante linea in un file di configurazione con solo modifiche cosmetiche.
9000,

3

Quando ho bisogno di scrivere uno script elaborato con varie opzioni di configurazione, uso Python con le librerie argparse e ConfigParser . Aiutano con l'implementazione ma il processo si applica a qualsiasi script shell:

  1. Cerca un file di configurazione. Se ne esiste uno, leggi tutte le impostazioni che ha in un dizionario / tabella di ricerca.
  2. Argomenti della riga di comando con nome di analisi. Per ogni argomento fornito, sovrascrivere il valore caricato dal file di configurazione se esiste. Per qualsiasi argomento non passato nella riga di comando e non nella configurazione, utilizzare un valore predefinito.
  3. Eseguire la funzione principale dello script
  4. Se il file di configurazione non esiste, scrivere su di esso i valori passati e / o predefiniti.

La mia preferenza è che un file di configurazione contenga le opzioni preferite quando lo script verrà usato ripetutamente, ma lascia che tutti gli argomenti della riga di comando abbiano la precedenza. Scrivi il file di configurazione usando quei parametri la prima volta che viene eseguito. Il file di configurazione può quindi essere condiviso e sottoposto a commit in un repository di codice.

Nel mio caso più recente, ho anche scritto i valori predefiniti nella [DEFAULT]sezione nella parte superiore del file di configurazione, quindi ho una sezione per ogni "ambiente" con le sostituzioni appropriate per ciascuno. L '"ambiente" è il primo parametro senza nome dello script. Quindi in questo caso i parametri sono scelti come predefiniti integrati -> file di configurazione predefinito -> valore della sezione del file di configurazione -> parametro della riga di comando . Un ulteriore parametro della riga di comando offre la possibilità di sovrascrivere la configurazione esistente con il valore dell'ultima corsa. Questo file di configurazione è scritto nella directory corrente, quindi si applica per progetto e può essere eseguito il commit con il resto del codice. Chiunque verifichi lo stesso progetto inizierà quindi con la stessa configurazione.


"Un ulteriore parametro della riga di comando offre la possibilità di sovrascrivere la configurazione esistente con l'ultimo valore della corsa." Questo è un approccio interessante. Un modo pratico per combinare i parametri con la configurazione.
Charlie Rudenstål,

+1, inoltre, consiglierei di impostare i valori predefiniti in un default.configfile situato nella stessa directory dello script, quindi cercare un file di configurazione ~/.scriptnameper sovrascrivere questi valori. In questo modo ogni valore ha un valore predefinito valido ed è più facile da mantenere.
Aaron,

2

La modifica dei segnaposto è soggetta a errori.

Vorrei andare con l'utilizzo di un file di configurazione.

La tua preoccupazione per la dipendenza è valida, tuttavia, non ricordo di aver usato troppi strumenti composti da un singolo file. Quindi teoricamente hai ragione, ma praticamente dovrebbe essere abbastanza OK.

Una terza opzione è quella di far scrivere al software di configurazione una nuova versione su misura specifica delle opzioni e dei parametri selezionati. Questo potrebbe essere più difficile da scrivere e testare ovviamente :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.