cfgdiff
Problem: Die komplette Konfiguration des Routers geschieht über Textdateien. Gerade wenn neue Versionen herauskommen und man updaten will, ist es mitunter schwierig, herauszufinden, welche neuen Parameter hinzugekommen sind, was sich verändert hat. Oder wenn man mehrere Router pflegt, möchte man vielleicht eine schnelle Übersicht haben, worin die Unterschiede in zwei Configdateien bestehen. Dabei geht es vor allem darum, welche Parameter anders konfiguriert sind. Normale diff-Programme versagen hier z.B. dann, wenn Parameter in anderer Reihenfolge aufgelistet sind. Auch interessiert z.B. nicht, ob Kommentarzeilen verändert wurden.
Lösung: Ein kleines Ruby-Skript parst die Konfig-Dateien, vergleicht jeden Parameter und gibt Unterschiede in folgender Form aus:
=C: IP_ROUTE_N=2 => 0 =C: HOST_3_IP=192.168.0.7 => 192.168.6.3 =C: OPT_SYSLOGD=yes => no =C: DNS_VERBOSE=yes => no =C: DOMAIN_NAME=intra.net => lan.fli4l =C: HOST_1_IP=192.168.0.5 => 192.168.6.1 =C: OPT_KLOGD=yes => no <N: HOST_8_NAME=thinkslow <N: HOST_13_NAME=fli4lwm001 <N: HOST_9_IP=192.168.0.30 >N: SYSLOGD_DEST_3=kern.info /var/log/dial.log
=C: bedeutet, dass die folgende Variable sich geändert hat.
<N: bedeutet, dass in der ersten Datei eine neue Variable vorhanden ist, die in der zweiten Datei nicht existiert.
>N: bedeutet, dass in der zweiten Datei eine neue Variable vorhanden ist, die in der ersten Datei nicht existiert.
- alle Kommentare werden überlesen, es werden nur Variablenwerte verglichen
Skript: (download: http://www.reintechnisch.de/pub/fli4l/)
def use $stderr.puts "use cfgdiff file1 file2" end if $*.length != 2 use exit 1 end $infile1 = $*[0] $infile2 = $*[1] if !File.file?( $infile1 ) $stderr.puts "File1 not found." use exit 1 end if !File.file?( $infile2 ) $stderr.puts "File2 not found." use exit 1 end def readcfg( file ) cfg = Hash.new File.foreach( file ) do |line| next if line =~ /^\s*#/ next if line =~ /^\s*$/ if line !~ /^\s*(\w+)\s*=\s*'(.*?)'/ $stderr.puts "Error in line: #{line}" exit 1 end var = $1 value = $2 cfg[var] = value #puts "[#{var}] [#{value}]" end cfg end $cfg1 = readcfg( $infile1 ) $cfg2 = readcfg( $infile2 ) $cfg1.each_pair do |var, value| if $cfg2[var] == nil puts "<N: #{var}=#{value}" else if $cfg1[var] != $cfg2[var] puts "=C: #{var}=#{value} => #{$cfg2[var]}" end $cfg2.delete(var) end end $cfg2.each_pair do |var,value| puts ">N: #{var}=#{value}" end
Zur Ausführung muß Ruby installiert sein. Für Windows bekommt man das Paket unter http://rubyinstaller.sourceforge.net/ Unter Linux sollte es bei jeder Distribution mit dabei sein. (debian: apt-get install ruby )
Das Skript als Datei "cfgdiff" speichern und es entweder mittels chmod 700 cfgdiff ausführbar machen (nur Linux) oder es mit "ruby cfgdiff file1 file2" auf der Kommandozeile/Shell starten.
Mehr zu Ruby
Fragen und Kommentare an mich: WinfriedMueller
Beispiele
Unterschiede Version 2.1.5 und 2.1.6 (27.03.2004, patch-4):
Es bestand die Aufgabe, einen 2.1.5 basierten fli4l auf 2.1.6 zu aktualisieren. Die alten Configs aus 2.1.5 sollten übernommen werden. Folglich brauchte ich die Information, welche Parameter in 2.1.6 neu hinzukamen oder sich geändert haben. Hierzu verglich ich die jungfreulichen Configs aus 2.1.5 gegenüber 2.1.6:
---- cfgdiff 215/base.txt 216/base.txt <N: MENU_LANGUAGE=german >N: MENU_LANGUAGES=de,en --> hier muss also MENU_LANGUAGE durch MENU_LANGUAGES ausgetauscht werden ---- cfgdiff 215/sshd.txt 216/sshd.txt >N: OPT_SFTPSERVER=no >N: SSHD_PUBLIC_KEYFILE_1=root@fli4l >N: SSHD_PUBLIC_KEYFILES_N=0 --> diese 3 neuen Parameter müssen hinzugefügt werden ---- cfgdiff 215/isdn.txt 216/isdn.txt <no changes> ---- cfgdiff 215/dsl.txt 216/dsl.txt <no changes> ---- cfgdiff 215/time.txt 216/time.txt <no changes> ---- cfgdiff 215/tools.txt 216/tools.txt >N: OPT_STRACE=no --> dieser neue Parameter muss hinzugefügt werden (strace ist hinzu gekommen)