Modifica del file di configurazione tramite uno script bash


9

Ho provato a scrivere un semplice script bash che userò per installare un'applicazione e aggiornarne il file di configurazione. Non riesco a far modificare il file di configurazione.

# DBHost=localhost
DBName=test
# DBPassword=

qualche suggerimento su come posso modificare sopra come sotto?

DBHost=localhost
DBName=database
DBPassword=password

Non riesco a credere che dobbiamo scrivere espressioni regolari soggette ad errori solo per fare questo compito molto comune. Dovrebbe esserci davvero uno strumento standardizzato come "update_config test.confg -uncomment_if_pressent DBHost = localhost".
bigjosh,

Risposte:


3

Il modo migliore dipende dal fatto che ti aspetti che il file venga modificato anche dagli umani, da quanto sia complesso il file e se desideri che lo script abbia la precedenza se sembra che qualcun altro desideri un valore diverso. Cioè, se il file contiene già DBPassword=swordfish, vuoi mantenerlo o sostituirlo con DBPassword=password?

Un modo comune di gestirlo è quello di avere una sezione del file delimitata da "commenti magici" e modificare solo la parte tra questi commenti. Ecco un modo per farlo con awk. Se i commenti magici non sono presenti, la nuova sezione viene aggiunta alla fine del file. Attenzione: codice non testato.

begin_marker='# BEGIN AUTOMATICALLY EDITED PART, DO NOT EDIT'
end_marker='# END AUTOMATICALLY EDITED PART'
new_section='DBHost=localhost
DBName=database
DBPassword=password'
export begin_marker end_marker
awk <file.conf >file.conf.new -v begin_marker="$begin_marker" -v begin_marker="$end_marker" -v new_section="$new_section" '
    1 {print}
    $0 == begin_marker && !changed {
        do {getline} while ($0 != end_marker); # discard old section content
        print new_section;
        print;
        changed = 1;
    }
    END {if (!changed) {print begin_marker; print new_section; print end_marker;}}
'
ln -f file.conf file.conf.old
mv -f file.conf.new file.conf

Questo approccio non funziona bene se il programma che legge il file di configurazione non supporta più righe impostando lo stesso elemento di configurazione. In tal caso, dovrai davvero rimuovere quelli vecchi. In questo caso, consiglierei di lasciare intatti i commenti e di aggiungere le proprie impostazioni alla fine.

grep -vE '^[[:blank:]]*(DBHost|DBName|DBPassword)=$' <file.conf >file.conf.new
cat <<EOF >>file.conf.new
DBHost=localhost
DBName=database
DBPassword=password
EOF
ln -f file.conf file.conf.old
mv -f file.conf.new file.conf

Hai testato questo codice? o è ancora non testato?
rubo77,


2

Se questo è tutto ciò di cui hai bisogno, potresti fare qualcosa del genere

sed  -i.bak -e 's/DBName=.*/DBName=database/' \
 -e 's/#* *DBHost=.*/DBHost=localhost/' \
 -e 's/#* *DBPassword=.*/DBPassword=password/' config.file

Questo copierà l'originale config.fileper config.file.bake apportare le modifiche necessarie.


2

Andrò con "ex" in modalità silenziosa:

ex -s $CONFIG_FILE << END_CMDS
%s/^#.DBHost/DBHOST/
%s/DBName=test/DBName=database/
%s/^#.DBPassword/DBPassword/
w!
q
END_CMDS

Il sedcomando di terdon è compatto ed efficiente. Ma l'interazione di un "documento qui" pieno di comandi ex e interpolazione di stringhe di shell può essere potente. Ad esempio, la password potrebbe essere sostituita come valore di una variabile di shell:

%s/^#.DBPassword=password/DBPassword=$PASSWORD/

Se usi vio vime hai familiarità con la modalità ':', è anche abbastanza semplice aggiungere nuove / migliori / diverse modifiche.


Mentre ex è potente, è difficile recuperare da errori (ad esempio quando manca una linea prevista). Qui puoi scappare senza alcun comportamento condizionale, ma questo non si generalizza così bene.
Gilles 'SO- smetti di essere malvagio' il
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.