• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[Gelöst] Frage zu Skript-Syntax

A

Anonymous

Gast
Hi zusammen,

ich habe für die Uni folgendes Skript gebastelt:
Code:
#!/bin/bash

# Dieses Skript bringt die Ausgabe der Switches über die angeschlossenen Geräte in eine lesbare Form

FILE=ips.txt
echo -e "IP-Adresse\tMAC-Adresse\tPort"
while read line; do # zeilenweise einlesen
  for `grep "=> 0x" $line`; do # leere und unnütze Zeilen überspringen
    IP=`echo $line|awk '{print $1}'|awk -F "." '{print $14"."$15"."$16"."$17}'` # IPs herausfiltern    
    MAC=`echo $line|awk '{print $3}'` # MACs herausfiltern    
    echo -e "$IP\t$MAC" # IPs und MACs ausgeben
  done
done<$FILE

Nur bekommen ich beim Ausführen immer:
Code:
./ips.sh: Zeile 10: ``grep " => 0x" $line`': Ist kein gültiger Bezeichner.
Was stimmt denn an der for-Schleife nicht? Irgendwie steh ich auf dem Schlauch :eek:ps:

Schöne Grüße
 

drcux

Hacker
Meiner Meinung nach ist es ein völlig falscher Ansatz:
Code:
liste=`grep "zeilen die ich brauche" ips.txt`
for zeile in $liste; do
    awk ........ $zeile
done
 
OP
A

Anonymous

Gast
DaBossDaChef schrieb:
while read line; do # zeilenweise einlesen
for HIER_FEHLT_DER VARIABELNAME in `grep "=> 0x" $line`; do # leere und unnütze Zeilen überspringen
IP=`echo $line|awk '{print $1}'|awk -F "." '{print $14"."$15"."$16"."$17}'` # IPs herausfiltern

Was stimmt denn an der for-Schleife nicht? Irgendwie steh ich auf dem Schlauch :eek:ps:

Das ganze ist so jedoch völlig verkompliziert durch unnütze Aneinanderreihungen von Befehlen, extrem schlechter Programmierstiel
das Ganze geht mit einem einzigen awk Kommando. (Mal so aus dem Bauch heraus ohne es auszuprobieren)
Code:
awk '  ~ "=> 0x" { split( $1, tmp, "." ) ; print tmp[14] "." tmp[15] "." tmp[16] "." tmp[17] "\t" $3 }'  ips.txt

wenn es nicht funktioniert dann man 3 bis 5 Zeilen deiner Orginaldatei und was dabei rauskommen soll hier ablegen

robi
 
OP
A

Anonymous

Gast
Also, es geht darum, dass wir an der Uni von den Switchen die IPs und Macs der angeschlossenen Geräte haben wollen, und an welchen Ports diese jeweils hängen. Das Ganze wird über SNMP abgefragt, aber dank der OIDs ist die Ausgabe ziemlich bescheiden. Aussehen tut es so:
Code:
== MAC Addresses: 1.3.6.1.2.1.17.4.3.1.1 ==

1.3.6.1.2.1.17.4.3.1.1.0.0.xxx.xxx.xxx.xxx => 0x000074b3bcde
1.3.6.1.2.1.17.4.3.1.1.0.1.xxx.xx.xx.xxx => 0x0001e656126f
1.3.6.1.2.1.17.4.3.1.1.0.4.xx.xxx.xxx.xxx => 0x00040b6e8cf8
1.3.6.1.2.1.17.4.3.1.1.0.5.xx.xx.xxx.xxx => 0x00051a47f078
1.3.6.1.2.1.17.4.3.1.1.0.8.xxx.xxx.xxx.xxx => 0x00087cec6880
1.3.6.1.2.1.17.4.3.1.1.0.9.xx.xx.xx.xxx => 0x00093d10239b
1.3.6.1.2.1.17.4.3.1.1.0.9.xx.xx.xxx.xxx => 0x00093d12767a
1.3.6.1.2.1.17.4.3.1.1.8.0.xx.xx.xx.xxx => 0x080037333ccc
usw.


== MAC Ports: 1.3.6.1.2.1.17.4.3.1.2 ==

1.3.6.1.2.1.17.4.3.1.2.0.0.xxx.xxx.xxx.xxx => 24
1.3.6.1.2.1.17.4.3.1.2.0.1.xxx.xx.xx.xxx => 8
1.3.6.1.2.1.17.4.3.1.2.0.4.xx.xxx.xxx.xxx => 24
1.3.6.1.2.1.17.4.3.1.2.0.5.xx.xx.xxx.xxx => 56
1.3.6.1.2.1.17.4.3.1.2.0.8.xxx.xxx.xxx.xxx => 121
usw.

Die Ausgabe sollte so aussehen:
Code:
IP-Adressen  MAC-Adresse  Port
xxx.xxx.xxx.xxx 0xblabla  xy

for HIER_FEHLT_DER VARIABELNAME in `grep "=> 0x" $line`
Haut auch nicht hin...

Ich weiss, dass der Stil schlecht ist, es soll nur aber erstmal funktionieren, verfeinern kann man immer noch. Ausserdem bin ich nicht so der Programmierkönig, lerne aber gerne dazu...
 

framp

Moderator
Teammitglied
So wie ich das sehe kann die Info die Du haben willst von Deinem Script nicht geliefert werden. Das Problem liegt in den Cardinalitäten der Beziehungen zwischen IPs, MACs und Ports.

Wenn Du DHCP hast kannst Du für ein und dieselbe MAC unterschiedliche IPs haben, die auch wieder auf unterschiedlichen Ports liegen können. Braucht ja nur jemand mit seinem Schlepptop von Ort A nach Ort B, die am selben Switch liegen, umzuziehen. Der einzige stabile Identifier ist die MAC, die eigentlich eineindeutig sein sollte. D.h. Du hast eine

1) 1-n Beziehung bei MAC zu Ports (Rechner wechselt am Switch)
2) 1-n Beziehung bei MAC zu IPs (DHCP liefert unterschieldiche IPs)

Die Frage ist also was für Info willst Du genau haben? Dann kann man das Script erstellen. In meinen Augen macht die folgende Tabelle Sinn wo die MAC am Anfang steht denn die identifiziert den Rechner eineindeutig. Dann wird dazu die jeweilige IP und der Port gelistet.

Code:
MAC Address - IPs(Ports)
44:55:66:77:88 192.168.0.5(7) 165.47.56(4711) 67.58.4.3(6789)
Ist es das was Du benötigst?
 
OP
A

Anonymous

Gast
kleine Änderung in der obrigen Zeile
Code:
awk '  $0 ~ "=> 0x" { split( $1, tmp, "." ) ; print tmp[14] "." tmp[15] "." tmp[16] "." tmp[17] "\t" $3 }'  ips.txt
Ergebnis;
Code:
xxx.xxx.xxx.xxx 0x000074b3bcde
xxx.xx.xx.xxx   0x0001e656126f
xx.xxx.xxx.xxx  0x00040b6e8cf8
xx.xx.xxx.xxx   0x00051a47f078
xxx.xxx.xxx.xxx 0x00087cec6880
xx.xx.xx.xxx    0x00093d10239b
xx.xx.xxx.xxx   0x00093d12767a
xx.xx.xx.xxx    0x080037333ccc
Eine Zuordnung zu den Ports kann ich aber aus deinem Testdatem nicht ableiten, da ich über so viele "x" keine Verknüpfung ableiten kann.

Eventuell hilft auch eine gezieltere Abfrage über snmp mal ein bischen in den Manpages blättern und mit snmpwalk rumprobieren.
Im Internet sollte es bestimmt auch fertige Scripte geben die solche Ausgaben für den import von scripten und ähnlichen aufbereiten.
Ich habe hier zwar auch welche, allerdings mit "falschen Copyright" für dieses Forum.

robi
 

HBtux

Member
Ich habe mal probeweise einige IP-Adressen eingesetzt....

Datei: ips.txt
Code:
== MAC Addresses: 1.3.6.1.2.1.17.4.3.1.1 ==

1.3.6.1.2.1.17.4.3.1.1.0.0.10.0.0.51 => 0x000074b3bcde
1.3.6.1.2.1.17.4.3.1.1.0.1.10.0.0.52 => 0x0001e656126f
1.3.6.1.2.1.17.4.3.1.1.0.4.10.0.0.53 => 0x00040b6e8cf8
1.3.6.1.2.1.17.4.3.1.1.0.5.10.0.0.54 => 0x00051a47f078
1.3.6.1.2.1.17.4.3.1.1.0.8.10.0.0.58 => 0x00087cec6880
1.3.6.1.2.1.17.4.3.1.1.0.9.10.0.0.59 => 0x00093d10239b
1.3.6.1.2.1.17.4.3.1.1.0.9.10.0.0.72 => 0x00093d12767a
1.3.6.1.2.1.17.4.3.1.1.8.0.10.0.0.73 => 0x080037333ccc

Datei: ports.txt (inkl. einer IP auf zwei Ports....!)
Code:
== MAC Ports: 1.3.6.1.2.1.17.4.3.1.2 ==

1.3.6.1.2.1.17.4.3.1.2.0.0.10.0.0.52 => 24
1.3.6.1.2.1.17.4.3.1.2.0.1.10.0.0.54 => 8
1.3.6.1.2.1.17.4.3.1.2.0.4.10.0.0.58 => 24
1.3.6.1.2.1.17.4.3.1.2.0.5.10.0.0.72 => 56
1.3.6.1.2.1.17.4.3.1.2.0.8.10.0.0.72 => 121

Script: ips.sh
Code:
#!/bin/bash

# Dieses Skript bringt die Ausgabe der Switches über die angeschlossenen Geräte in eine lesbare Form

FILE=ips.txt
FILE_PORTS=ports.txt

echo -e "IP-Adresse\tMAC-Adresse\tPort"

while read line; do # zeilenweise einlesen
  # leere und unnütze Zeilen überspringen
        echo $line | grep "=> 0x" >/dev/null 2>&1
        if [ "$?" = "0" ]; then
            IP=`echo $line|awk '{print $1}'|awk -F "." '{print $14"."$15"."$16"."$17}'` # IPs herausfiltern
            MAC=`echo $line|awk '{print $3}'` # MACs herausfiltern

            PORT=`grep "${IP} => " $FILE_PORTS | awk '{print $3}' | sed -e 'N; s/\n/ /'`
            [ "$PORT" = "" ] && PORT="-"
            echo -e "$IP\t$MAC\t$PORT" # IPs und MACs ausgeben
        fi
done < $FILE

Ergebnis:
Code:
HBtux:/tmp # ./ips.sh
IP-Adresse      MAC-Adresse     Port
10.0.0.51       0x000074b3bcde  -
10.0.0.52       0x0001e656126f  24
10.0.0.53       0x00040b6e8cf8  -
10.0.0.54       0x00051a47f078  8
10.0.0.58       0x00087cec6880  24
10.0.0.59       0x00093d10239b  -
10.0.0.72       0x00093d12767a  56 121
10.0.0.73       0x080037333ccc  -

Dein Fehler lag in dieser Zeile....
Code:
for `grep "=> 0x" $line`; do

ich habe es so gelöst...
Code:
echo $line | grep "=> 0x"
if [ "$?" = "0" ]; then
...
fi
 
OP
A

Anonymous

Gast
Danke euch für die Antworten!
@HBtux
Es funktioniert, danke.

Jetzt muss ich mir das mal genau anschauen, ob die IP-Port Zuordnung stimmt.
 

framp

Moderator
Teammitglied
@HBtux: Interessanter Lösungsweg von Dir per grep auf die Datei einen HashLookup zu implementieren.
 

HBtux

Member
framp schrieb:
@HBtux: Interessanter Lösungsweg von Dir per grep auf die Datei einen HashLookup zu implementieren.
War das ironisch gemeint oder ist der Lösungsweg wirklich interessant.

Meistens kann man es noch etwas einfacher lösen.
Aber auf die Schnelle .... und hauptsache es funktioniert.
 

framp

Moderator
Teammitglied
HBtux schrieb:
War das ironisch gemeint oder ist der Lösungsweg wirklich interessant.
Nee, wie kommst Du darauf dass es ironisch gemeint war? Ist ehrlich eine für mich neue und zugegebenermassen pragmatische Art ein HashLookup aus einem File zu machen. Ich hätte das File geparsed und ein InstorageArray zum Lookup aufgebaut. Deine Implementierung ist für dieses Problem - quadratisch - praktisch und gut :roll: Ist also wirklich als :up: gemeint.
 
Oben