在bash中读取配置文件的最佳方法

在bash中读取配置文件的最佳方法是什么?
例如,您有一个脚本,并且不愿意在每次调用脚本时手动填写所有配置。

编辑1:我想我没说清楚,所以:我想要的是……我有一个类似的配置文件

variable_name value variable_name value ... 

我想读一读 我知道我可以为我正在寻找的论点而烦恼……但也许有一种更聪明的方式:)

正如mbiber所说, source另一个档案。 例如,您的配置文件(比如some.config )将是:

 var1=val1 var2=val2 

你的脚本可能看起来像:

 #! /bin/bash # Optionally, set default values # var1="default value for var1" # var1="default value for var2" . /path/to/some.config echo "$var1" "$var2" 

/etc/default的许多文件通常以类似的方式用作其他shell脚本的配置文件。 这里的post中一个非常常见的例子是/etc/default/grub 。 此文件用于设置GRUB的配置选项,因为grub-mkconfig是一个shell脚本来源它:

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

如果您真的必须处理表单的配置:

 var1 some value 1 var2 some value 2 

然后你可以这样做:

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

(你也可以做一些像eval "$var=$value"这样的东西,但这比采购脚本更冒险。你可能会无意中破坏它比源文件更容易。)

显然,我不是这里的bash专家,但不管您使用何种语言,概念都不应该有所不同:

一个例子

在下面的示例中,您可以使用(非常)基本脚本来设置字符串或打印字符串,如配置文件中所设置:

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

然后

  • 要将字符串设置到配置文件中:

     $ '/home/jacob/Bureaublad/test.sh' set "Een aap op een fiets, hoe vind je zoiets?" 
  • 随后,打印出“configfile”中定义的字符串:

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

当然,在一个真正应用的脚本中,你需要添加很多东西来确保参数是正确的,决定在输入不正确时做什么,设置文件不存在等等,但是:

这是基本的想法

使用source. 加载文件。

 source /path/to/file 

要么

 . /path/to/file 

还建议在加载文件之前检查文件是否存在,因为如果配置文件不存在,您不希望继续运行脚本。

我正在使用这个……

 #!/bin/bash CFG_FILE=/etc/test.conf CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') eval "$CFG_CONTENT" 

使用sed解析Conf文件,然后将其评估为简单变量asignments

第一个sed解析键值(支持=用空格包围)

第二个sed删除=符号周围的空格以获得有效的变量对齐

可以添加进一步的sed治疗

将删除conf文件中所有其他不匹配的文本(包括#或;评论和其他)

请注意,也可以从此配置文件中评估单行shell命令!

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