Bei einigen Servern habe ich einen Cronjob, der ruft ein Shellskript auf, welches den IST Zustand einiger Dienste auflistet. Also, auf einem Server, welche Mysql- und Postgres-Datenbankschemata es gibt, auf dem nächsten welche Apache VHosts existieren und auf dem Fileserver welche Samba-Shares usw.
Schlussendlich landet es auf einem Wiki (Dokuwiki in diesem Fall - hier sind die Seiten Txt-Dateien im Filesystem - das macht die Sache sehr einfach).
Beim Samba Server war es bis anhin recht unschön, weil umständlich gecodet. Nun habe ich 3 kleine Funktionen hinzugefügt, mit denen ich (endlich :-)) eine INI Datei parsen kann.
Die Funktionen kann man in eine Datei mit Leserechten (ohne Execute-Recht) auslagern, die man im Skript sourct (per source oder Punkt-Kommando).
- _getInisections [Name der Ini-Datei]
listet alle Sektionstitel auf - _getInisectiondata [Name der Ini-Datei] [Name der Sektion]
listet die angegebene Sektion auf. Mit dieser Ausgabe sieht man eine Sektion alleinstehend - und kann sich die Variablen herausziehen … aber wenn man die Variablen kennt, gibt es noch die nächste Funktion - _getIniValue [Name der Ini-Datei] [Name der Sektion] [Name der Variable]
gibt den Wert einer Variable aus der angegebenen Sektion zurück
In der Samba-Konfiguration (/etc/samba/smb.conf) sind die Variablen und Werte nicht zwingend ab Zeilenanfang - daher sind im Regex Leerzeichen und Tabs hinzugefügt.
# Helper for ini files: get all sections
# param1 - name of the ini file
function _getInisections(){
local myfile=$1
grep ”^\[” $myfile | sed ’s,^\[,,’ | sed ’s,\],,’
}
# Helper for ini files: get all content inside a section
# param1 - name of the ini file
# param2 - name of the section in ini file
function _getInisectiondata(){
local myfile=$1
local mysection=$2
mysection=$( sed ”s#/#\/#g” <<< ”$mysection” )
sed -e ”0,/^\[${mysection}\]/ d” -e ’/^\[/,$ d’ $myfile | grep -v ”^[#;]”
}
# Helper for ini files: get a value of a variable in a given section
# param1 - name of the ini file
# param2 - name of the section in ini file
# param3 - name of the variable to read
function _getIniValue(){
local myfile=$1
local mysection=$2
local myvarname=$3
_getInisectiondata ${myfile} ${mysection} | grep ”[^\a][\ \t]*${myvarname}[\ \t]*=.*” | cut -f 2 -d ”=” | sed -e ’s,^\ *,,’
}
Und als Anwendungsbeispiel: ein Snippet mit einem Loop über die Samba-Konfiguration. Ausgegeben wird eine Tabelle mit Name des Shares, Beschreibung (Wert “comment”) und Pfad des Shares (Wert “path”):
smbconf=/etc/samba/smb.conf
# Ausgabe des Tabellen-Header in Wiki-Syntax
echo ”^Share^Kommentar^Pfad^”
# Loop ueber alle Sektionen
for mysection in `_getInisections $smbconf | grep -v global`
do
# Ini-Werte aus der Sektion lesen
myComment=`_getIniValue ${smbconf} ${mysection} ”comment”`
mypath=`_getIniValue ${smbconf} ${mysection} ”path”`
# Ausgabe der Tabellen-Zeile - Pipes sind Spaltentrenner
echo ”|${mysection}|${myComment}|${mypath}|”
done
UPDATES:
- 15.05.2019: Korrektur der fehlenden Backslahes (die wirft das Blogtool immer raus, wenn man es nicht als Html-Entity schreibt) plus verbessertes Handling mit laschen Regex und Leerzeichen. Danke an Frank!
- 04.03.2021: Sektionen mit eckigen Klammern aus Kommentaren ignorieren. Zusätzlich werden Kommentare mit Semikolon am Anfang ebenfalls ignoriert. Ein local macht eine Variable nur innerhalb der Funktion bekannt.
- 09.02.2022 Update von _getIniValue: [^\a] statt ^
- 19.03.2023: Ein Follower Projekt: Ich habe aus der class like Bash Funktionen erstellt. Mit Validator und anständiger Dokumentation https://www.axel-hah … docs/bash_iniparser/