在 bash 中读取配置文件的最佳方法是什么?
例如,您有一个脚本,但不愿意每次调用该脚本时手动填写所有配置。
编辑 1:我想我没有说清楚,所以:我想要的是...我有一个像
variable_name value
variable_name value ...
我想读一下。我知道我可以通过 grep 来找到我要找的参数……但也许还有更智能的方法 :)
答案1
正如 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 脚本的配置文件。此处帖子中的一个非常常见的例子是/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"
,但这比获取脚本更危险。您可能会比获取源文件更容易无意中破坏它。)
答案2
使用source
或.
加载文件。
source /path/to/file
或者
. /path/to/file
还建议在加载文件之前检查该文件是否存在,因为如果配置文件不存在,您就不会继续运行脚本。
答案3
显然,我不是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?"
随后,打印出“配置文件”中定义的字符串:
$ '/home/jacob/Bureaublad/test.sh' print Een aap op een fiets, hoe vind je zoiets?
当然,在实际应用的脚本中,您需要添加很多东西来确保参数正确,决定当输入不正确、设置文件不存在等时该做什么,但是:
这是基本思想
答案4
#------------------------------------------------------------------------------
# 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