¿Cuál es la mejor manera de leer un archivo de configuración en bash?
Por ejemplo, tiene un script y no está dispuesto a completar toda la configuración manualmente cada vez que llama al script.
Edición 1: creo que no lo dejé claro, así que: lo que quiero es ... Tengo un archivo de configuración que es como
variable_name value
variable_name value ...
y quiero leer eso Sé que podría entenderlo por los argumentos que estoy buscando más o menos ... pero tal vez haya una forma más inteligente :)
Como dijo mbiber, source
otro archivo. Por ejemplo, su archivo de configuración (digamos some.config
) sería:
var1=val1
var2=val2
Y tu guión podría verse así:
#! /bin/bash
# Optionally, set default values
# var1="default value for var1"
# var1="default value for var2"
. /path/to/some.config
echo "$var1" "$var2"
Los muchos archivos en /etc/default
generalmente sirven como archivos de configuración para otros scripts de Shell de manera similar. Un ejemplo muy común de publicaciones aquí es /etc/default/grub
. Este archivo se utiliza para establecer las opciones de configuración para GRUB, ya que grub-mkconfig
es un script de Shell que lo origina:
sysconfdir="/etc"
#…
if test -f ${sysconfdir}/default/grub ; then
. ${sysconfdir}/default/grub
fi
Si realmente debe procesar la configuración del formulario:
var1 some value 1
var2 some value 2
Entonces podrías hacer algo como:
while read var value
do
export "$var"="$value"
done < /path/to/some.config
(También podría hacer algo como eval "$var=$value"
, pero eso es más riesgoso que obtener un script. Inadvertidamente podría romperlo más fácilmente que un archivo de origen).
Obviamente, no soy el especialista bash
aquí, pero el concepto no debería ser diferente en el idioma que uses:
En el ejemplo a continuación, puede usar un script (muy) básico para set una cadena, o print una cadena, como se establece en su archivo de configuración:
#!/bin/bash
# argument to set a new string or print the set string
arg=$1
# possible string as second argument
string=$2
# path to your config file
configfile="$HOME/stringfile"
# if the argument is: "set", write the string (second argument) to a file
if [ "$arg" == "set" ]
then
echo "$string" > $configfile
# if the argunment is "print": print out the set string, as defined in your file
Elif [ "$arg" == "print" ]
then
echo "$( cat $configfile )"
fi
Para establecer una cadena en su archivo de configuración:
$ '/home/jacob/Bureaublad/test.sh' set "Een aap op een fiets, hoe vind je zoiets?"
Posteriormente, para imprimir la cadena, como se define en su "archivo de configuración":
$ '/home/jacob/Bureaublad/test.sh' print
Een aap op een fiets, hoe vind je zoiets?
Por supuesto, en una secuencia de comandos aplicada real, debe agregar muchas cosas para asegurarse de que los argumentos sean correctos, decidir qué hacer cuando la entrada es incorrecta, el archivo de configuración no existe, etc., pero:
Esta es la idea básica
Use source
o .
para cargar en un archivo.
source /path/to/file
o
. /path/to/file
También se recomienda verificar si el archivo existe antes de cargarlo porque no desea continuar ejecutando su script si no hay un archivo de configuración.
Estoy usando este ...
#!/bin/bash
CFG_FILE=/etc/test.conf
CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g')
eval "$CFG_CONTENT"
El archivo Conf se analiza con sed y luego se evalúa como tareas variables simples
Primer análisis de valores clave de sed (admite también = rodeado de espacios)
Second sed elimina espacios alrededor = signo para asignación variable válida
Se puede agregar más tratamiento de sed.
Se eliminarán todos los demás textos que no coincidan en el archivo conf (incluidos # o; comentario y otros)
¡Tenga en cuenta que los comandos de Shell de una sola línea también se pueden evaluar desde este archivo de configuración!
#------------------------------------------------------------------------------
# parse the ini like $0.$Host_name.cnf and set the variables
# cleans the unneeded during after run-time stuff. Note the MainSection
# courtesy of : http://mark.aufflick.com/blog/2007/11/08/parsing-ini-files-with-sed
#------------------------------------------------------------------------------
doParseConfFile(){
# set a default cnfiguration file
cnf_file="$run_unit_bash_dir/$run_unit.cnf"
# however if there is a Host dependant cnf file override it
test -f "$run_unit_bash_dir/$run_unit.$Host_name.cnf" \
&& cnf_file="$run_unit_bash_dir/$run_unit.$Host_name.cnf"
# yet finally override if passed as argument to this function
# if the the ini file is not passed define the default Host independant ini file
test -z "$1" || cnf_file=$1;shift 1;
test -z "$2" || ini_section=$2;shift 1;
doLog "DEBUG read configuration file : $cnf_file"
doLog "INFO read [$ini_section] section from config file"
# debug echo "@doParseConfFile cnf_file:: $cnf_file"
# coud be later on parametrized ...
test -z "$ini_section" && ini_section='MAIN_SETTINGS'
doLog "DEBUG reading: the following configuration file"
doLog "DEBUG ""$cnf_file"
( set -o posix ; set ) | sort >"$tmp_dir/vars.before"
eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
-e 's/#.*$//' \
-e 's/[[:space:]]*$//' \
-e 's/^[[:space:]]*//' \
-e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \
< $cnf_file \
| sed -n -e "/^\[$ini_section\]/,/^\s*\[/{/^[^#].*\=.*/p;}"`
( set -o posix ; set ) | sort >"$tmp_dir/vars.after"
doLog "INFO added the following vars from section: [$ini_section]"
cmd="$(comm -3 $tmp_dir/vars.before $tmp_dir/vars.after | Perl -ne 's#\s+##g;print "\n $_ "' )"
echo -e "$cmd"
echo -e "$cmd" >> $log_file
echo -e "\n\n"
sleep 1; printf "\033[2J";printf "\033[0;0H" # and clear the screen
}
#eof func doParseConfFile