Melhor maneira de ler um arquivo de configuração no bash

11

Qual é a melhor maneira de ler um arquivo de configuração no bash?
Por exemplo, você tem um script e não está disposto a preencher toda a configuração manualmente toda vez que chama o script.

Editar 1: Acho que não deixei claro, então: o que eu quero é ... eu tenho um arquivo de configuração que é como

variable_name value  
variable_name value ...  

e eu quero ler isso. Eu sei que poderia simplesmente usar os argumentos que estou procurando, ou talvez ... mas talvez haja uma maneira mais inteligente:)

    
por IcyIcyIce 08.03.2016 / 16:38

5 respostas

21

Como mbiber disse, source outro arquivo. Por exemplo, seu arquivo de configuração (digamos, some.config ) seria:

var1=val1
var2=val2

E o seu script pode ser parecido com:

#! /bin/bash

# Optionally, set default values
# var1="default value for var1"
# var1="default value for var2"

. /path/to/some.config

echo "$var1" "$var2"

Os muitos arquivos em /etc/default geralmente servem como arquivos de configuração para outros scripts de shell de maneira semelhante. Um exemplo muito comum de postagens aqui é /etc/default/grub . Este arquivo é usado para definir opções de configuração para o GRUB, pois grub-mkconfig é um script de shell que o origina:

sysconfdir="/etc"
#…
if test -f ${sysconfdir}/default/grub ; then
  . ${sysconfdir}/default/grub
fi

Se você realmente precisa processar a configuração do formulário:

var1 some value 1
var2 some value 2

Então você poderia fazer algo como:

while read var value
do
    export "$var"="$value"
done < /path/to/some.config

(Você também pode fazer algo como eval "$var=$value" , mas isso é mais arriscado do que pesquisar um script. Você pode inadvertidamente quebrá-lo mais facilmente do que um arquivo originado.)

    
por muru 08.03.2016 / 22:59
4

Obviamente, não sou o especialista bash aqui, mas o conceito não deve ser diferente em qualquer idioma que você use:

Um exemplo

No exemplo abaixo, você pode usar um script (muito) básico para definir uma string, ou imprimir uma string, como definido no seu arquivo de configuração:

#!/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

Então

  • Para definir uma string no seu arquivo de configuração:

    $ '/home/jacob/Bureaublad/test.sh' set "Een aap op een fiets, hoe vind je zoiets?"
    
  • Posteriormente, para imprimir a string, conforme definido em seu "arquivo de configuração":

    $ '/home/jacob/Bureaublad/test.sh' print
    Een aap op een fiets, hoe vind je zoiets?
    

Naturalmente, em um script real aplicado, você precisa adicionar muitas coisas para garantir que os argumentos estejam corretos, decidir o que fazer quando a entrada estiver incorreta, o arquivo de configurações não existir, etc., mas:

Esta é a ideia básica

    
por Jacob Vlijm 08.03.2016 / 17:04
3

Use source ou . para carregar em um arquivo.

source /path/to/file

ou

. /path/to/file

Também é recomendável verificar se o arquivo existe antes de carregá-lo, porque você não deseja continuar executando o script se um arquivo de configuração não estiver presente.

    
por mbiber 08.03.2016 / 16:46
0

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

O arquivo Conf é analisado com sed e, em seguida, avaliado como um simples atributo de variável

Primeiros valores da chave de análise sed (suporta também = rodeado de espaços)

Segundo sed remove espaços em torno de = sinal para atribuição variável válida

Mais tratamento sed pode ser adicionado

Todos os outros textos não correspondentes no arquivo conf serão removidos (incluindo # ou; comentário e outros)

Esteja ciente de que os comandos de shell de linha única também podem ser avaliados a partir deste arquivo de configuração!

    
por smARTin 24.02.2017 / 15:07
0
#------------------------------------------------------------------------------
# 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/^\(.*\)=\([^\"']*\)$/=\"\"/" \
        < $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 "3[2J";printf "3[0;0H" # and clear the screen
}
#eof func doParseConfFile
    
por Yordan Georgiev 21.07.2017 / 13:13

Tags