#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $ini='test.sh'; print Dumper({exe_ini($ini)}); print "#"x80,"\n"; print Dumper({parse_ini($ini)}); # der sicherste Weg: # hier lese ich erst die Datei ein, # um sie Schlüssel zu bekommen. # Danach führe ich die Datei in der Shell aus # und lese dann die vorher geparsten # und nun gesetzten variablen aus. # Ich lese alle Variablen auf einmal aus, # das get recht schnell, # da der Shellinterpreter nur einmal ausgeführt werden muss. sub exe_ini { my $file=shift; my %keys; # alle Schlüssel aus der Datei open(my $fh, '<', $file) or die "Error open $file ($!)\n"; while(my $line=<$fh>) { # Ein Schlüssel ist ein wort, # vor dem nur leerzeichen sind # und auf dem ein "=", # mit möglichen leerzeichen dazwischen, # folgt $keys{$1}++ if($line=~/^\s*(\w+)\s*=/); } close ($fh); # liste aller Schlüssel my @list=keys(%keys); # shellkomando zusammenbauen my $cmd=''; # für jeden Schlüssel ein echo $cmd.="echo \\\$$_; " for(@list); #alles ausführen my @vals=qx{sh -c ". $file; $cmd"}; # Zeilenumbrüche weg chomp(@vals); # Schlüssel und Werte zusammenführen @keys{@list}=@vals; return %keys } # parsen von "Hand" # Zeile für Zeile einlesen, # schlüssel=wert paare suchen. # Schauen ob der wert ein schlüsselaufruf ist, # wenn dann neuen Wert ermitteln. sub parse_ini { my $file=shift; my %keys; open(my $fh, '<', $file) or die "Error open $file ($!)\n"; while(my $line = <$fh>) { # wir lesen das Schlüssel-Wert-Paar if($line =~/^\s*(\w+)="([^"]*)"/ || $line=~/^\s*(\w+)=(.*?)(?:;|$)/) { my $key=$1; my $val=$2; $val=~s/\$\{([^\}]+)\}/$keys{$1}/g; $val=~s/\$(\w+)/$keys{$1}/g; $keys{$key}=$val; } } close($fh); return %keys; }