bashで設定ファイルを読み取る最良の方法


23

bashで設定ファイルを読み取る最良の方法は何ですか?
たとえば、スクリプトがあり、スクリプトを呼び出すたびにすべての構成を手動で入力することはできません。

編集1:私はそれを明確にしていないと思うので、私が欲しいのは...のような設定ファイルがあります

variable_name value  
variable_name value ...  

そして、私はそれを読みたいです。私は私が探している引数のためにそれをただグレップすることができることを知っています...しかし、おそらくもっとインテリジェントな方法があるかもしれません:)


2
どのような構成を意味するのかを示す必要があります。例を提供してください。
ムル

Unix&Linux StackExchangeの非常に似た質問も参照してください。
マイケル

回答:


38

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通常、多くのファイルは、同様の方法で他のシェルスクリプトの構成ファイルとして機能します。ここの投稿からの非常に一般的な例は/etc/default/grubです。このファイルは、GRUBの構成オプションを設定するために使用されますgrub-mkconfig

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"、スクリプトを入手するよりもリスクが高くなります。ソースファイルよりも簡単に破損する可能性があります。)


それは素晴らしい方法です。 "="の代わりにsed代替空白を使用できます
-IcyIcyIce

1
@IcyIcyIceしないでください。なぜ=最初からそれを書くことができないのですか?
ムル

1
@IcyIcyIceそれはそうあるべき姿です。さまざまなファイルでシェルコードを使用でき/etc/defaultます。無知なユーザーがrootとして実行されている何かの構成にアクセスできる場合、それはすでに失われた原因です。
ムル

1
@IcyIcyIceはあなたの教師に彼らが望むものを明確にしてもらいます。ソフトウェア開発の学習の一部は、要件を明確に知ることです。
ムル

1
@IcyIcyIce更新を参照してください。
ムル

4

明らかに、私は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?

もちろん、実際に適用されるスクリプトでは、引数が正しいことを確認し、入力が正しくない場合、設定ファイルが存在しない場合の対処方法などを決定するために多くのものを追加する必要がありますが、

これが基本的な考え方です


おかげで、私はちょうど私が私はそれを明確にするdidntのだと思う質問を更新しています...しかし、単純な例では、これはOFC魅力のように動作します
IcyIcyIce

4

sourceまたは.を使用してファイルをロードします。

source /path/to/file

または

. /path/to/file

また、構成ファイルが存在しない場合はスクリプトの実行を継続したくないため、ロードする前にファイルが存在するかどうかを確認することをお勧めします。


0

私はこれを使用しています...

#!/bin/bash

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

confファイルはsedで解析され、単純な変数割り当てとして評価されます

キー値を解析する最初のsed(サポート=スペースで囲まれている)

2番目のsedは、有効な変数割り当ての=記号の前後のスペースを削除します

さらなるsed治療を追加できます

confファイル内の一致しない他のすべてのテキストは削除されます(#または;の解説など)

単一行のシェルコマンドもこの設定ファイルから評価できることに注意してください!


1
の無駄な使用catsed連続して2回呼び出すのはなぜですか?あなたことができ連鎖sedそうのようなコマンド:sed -r '/[^=]+=[^=]+/!d;s/\s+=\s/=/g'
デビッド・フェルスター

また、このsedコマンドは、質問内のサンプル構成ファイルエントリの空の出力を生成します。-1
デビッドフォースター

1
もう一つの可能な改善:使用.サブプロセスの出力を保持する代わりに、一時的な変数のコマンドおよびプロセスのリダイレクトを:. <(sed ... "$CFG_FILE")
デビッド・フェルスター

もちろん、私の例では、設定ファイルのようなkey = valueを使用しています。「キー値」よりも良い方法です。key = valueを使用すると、私の例は機能します。あなたのsedコマンドの連鎖はより良いと私は認めますが、ソースコマンドはファイルを期待しているので:を使用できますeval $(sed -r '/[^=]+=[^=]+/!d;s/\s+=\s/=/g' "$CFG_FILE")
smARTin

はい、.ファイルを期待し、プロセス置換はファイルに展開されます。. <(echo echo foo)Bash v4.3.11で期待どおりに動作します。小さな例では、おそらく重要ではありません。ただし、コマンド置換を介して複数のキロバイトを渡したくないです。
デビッドフォースター

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/^\(.*\)=\([^\"']*\)$/\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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.