以下に説明するように、分割データを含む構成ファイルがあります。シェルスクリプトを使用して各変数にアクセスします。これを達成するためにsedコマンドを使用していますが、変数の設定を忘れた場合などの問題に直面しました。例: name [APP1] 名は [APP2] になります。
構成ファイル:
[APP1]
name=Application1
StatusScript=/home/status_APP1.sh
startScript=/home/start_APP1.sh
stopScript=/home/stop_APP1.sh
restartScript=/home/restart.APP1.sh
[APP2]
name=Application2
StatusScript=/home/status_APP2.sh
startScript=/home/start_APP2.sh
stopScript=/home/stop_APP2.sh
restartScript=/home/restart.APP2.sh
logdir=/log/APP2/
.
.
.
.
.
[APPN]
name=ApplicationN
StatusScript=/home/status_APPN.sh
startScript=/home/start_APPN.sh
stopScript=/home/stop_APPN.sh
restartScript=/home/restart.APPN.sh
logdir=/log/APPN
シェルコマンドの使用:
sed -nr "/^\[APP1\]/ { :l /^name[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}"
この問題を解決する方法はありますか?特定のセクションに特定の変数が設定されていない場合は、変数の値としてnullまたは0を渡します。
答え1
設定を明確な形式に解析し、最新バージョンの連想配列として読みますbash
。
awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf
次に、すべてのセクションヘッダーを探し、awk
変数をapp
そのセクションヘッダーの内容に設定します。その後、各後続行の前に対応する値を追加し、その後にドットを追加します。
これにより、次のような出力が生成されます。
APP1.name=Application1
APP1.StatusScript=/home/status_APP1.sh
APP1.startScript=/home/start_APP1.sh
APP1.stopScript=/home/stop_APP1.sh
APP1.restartScript=/home/restart.APP1.sh
APP2.name=Application2
APP2.StatusScript=/home/status_APP2.sh
APP2.startScript=/home/start_APP2.sh
APP2.stopScript=/home/stop_APP2.sh
APP2.restartScript=/home/restart.APP2.sh
APP2.logdir=/log/APP2/
APP2
セクションがない場合、その行name
はAPP2.name
表示されません。
次に連想配列として読みますbash
。
declare -A conf
while IFS='=' read -r key value; do
conf[$key]="$value"
done < <(awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf)
これでconf
構成変数を照会できます。
printf 'The stopScript for APPN is "%s"\n' "${conf[APPN.stopScript]}"
が返されます
The stopScript for APPN is "/home/stop_APPN.sh"
存在しない値を照会すると、空の文字列が生成されます。
このawk
コマンドは、次のsed
コマンドに置き換えることもできます。
sed -n \
-e '/^\[/{s/[][]//g;h;}' \
-e '/=/{H;g;s/\n/./;p;s/\..*//;h;}' file.conf
展開してコメントする:
/^\[/{ # handle section headers
s/[][]//g; # remove [ and ]
h; # put into the hold-space
}
/=/{ # handle settings
H; # append the line to the hold-space with newline as delimiter
g; # get the hold-space
s/\n/./; # replace the newline with a dot
p; # output
s/\..*//; # remove everything after the dot
h; # put back into the hold-space
}
答え2
次のシェル関数を作成できます。
printSection()
{
section="$1"
found=false
while read line
do
[[ $found == false && "$line" != "[$section]" ]] && continue
[[ $found == true && "${line:0:1}" = '[' ]] && break
found=true
echo "$line"
done
}
その後、printSectionをコマンドのように使用し、次のようにセクションをパラメータとして渡すことができます。
printSection APP2
パラメータを取得するには、次のように単純なsedを使用できます。
printSection APP2 | sed -n 's/^name=//p'
これは標準入力で実行され、標準出力に書き込まれます。したがって、設定ファイルの例が /etc/application.conf で、APP2 名を app2name 変数に保存する場合は、次のように作成します。
app2name=$(printSection APP2 | sed -n 's/^name//p/' < /etc/applications.conf)
または、次のように関数に引数部分を作成し、sedを完全にスキップすることもできます。
printValue()
{
section="$1"
param="$2"
found=false
while read line
do
[[ $found == false && "$line" != "[$section]" ]] && continue
[[ $found == true && "${line:0:1}" = '[' ]] && break
found=true
[[ "${line%=*}" == "$param" ]] && { echo "${line#*=}"; break; }
done
}
その後、次のように変数を割り当てることができます。
app2name=$(printValue APP2 name < /etc/applications.conf)
答え3
Gitにアクセスできる場合は、そのconfig
機能を「乱用」して構成ファイルを照会できます。
git config --file /etc/applications.cfg --get APPN.stopScript
section.key=value
パラメーターを使用して、すべてのキーと値のペアを次の形式でリストすることもできます。--list
git config --file /etc/applications.cfg --list
しかし、個々のセクションをリストする方法はわかりません。