• Liebe User, bitte beachtet folgendes Thema: Was im Forum passiert, bleibt im Forum! Danke!
  • Hallo Gemeinde! Das Problem leidet zurzeit unter technischen Problemen. Wir sind da dran, aber das Zeitkontingent ist begrenzt. In der Zwischenzeit dürfte den meisten aufgefallen sein, dass das Erstellen von Posts funktioniert, auch wenn das Forum erstmal eine Fehlermeldung wirft. Um unseren Löschaufwand zu minimieren, bitten wir euch darum, nicht mehrmals auf 'Post Reply' zu klicken, da das zur Mehrfachposts führt. Grußworte.

bisschen hilfe bei nem bash-script (billiges stringrumgehample)

bog

Mitglied seit
02.08.2002
Beiträge
10.121
Reaktionen
0
Ort
auf dem mutterschiff
ich hab grad meine router-firmware dahingehend gepatcht, dass sie aus dem dhcp-paket rfc3442-konforme classless static routes parsed und diese dann als einen string per environment-variable an ein anzugebendes script uebergibt.

das aber nur zum drumherum. die variable sieht so aus:
Code:
sroutes=193.158.137.14/32 87.155.159.254 87.140.255.0/25 87.155.159.254 87.141.128.0/17 87.155.159.254 193.158.34.0/23 87.155.159.254 194.25.134.197/32 87.155.159.254 217.6.164.40/31 87.155.159.254 217.6.164.48/29 87.155.159.254 217.6.164.42/32 87.155.159.254 217.6.164.45/32 87.155.159.254 217.6.164.46/31 87.155.159.254 217.6.167.128/26 87.155.159.254
stellt sich also in der form "zielnetz1/mask1 gateway1 zielnetz2/mask2 gateway2 ..." dar.
das ganze sollte dann zu befehlen dieser form verarbeitet werden:
Code:
/sbin/route add -host zielnetz1/mask1 gw gateway1 dev vlan8
/sbin/route add -net zielnetz2/mask2 gw gateway2 dev vlan8
in diesem fall ist mask1 == 32, daraus folgt der -host parameter. fuer alle anderen (kleineren) werte von mask ist der parameter -net

da ich von stringspielereien unter bash keinerlei ahnung hab, weiss ich nicht, wie ich da ansetzen sollte. gibts in bash arrays? regex matching? help? :)
 
Mitglied seit
15.05.2003
Beiträge
11.307
Reaktionen
8
Ort
Fortuna 1895 Düsseldorf
hab grad keine zeit da gross drauf einzugehen. ja es gibt arrays in bash.

wirf mal einen blick auf den advanced bash scripting guide, speziell part 5 chapter 26

http://tldp.org/LDP/abs/html/

€: jetzt hab ich doch rumgefrickelt :ugly:

Code:
#!/bin/bash

array=( 193.158.137.14/32 87.155.159.254 87.140.255.0/25 87.155.159.254 87.141.128.0/17 87.155.159.254 193.158.34.0/23 87.155.159.254 194.2
5.134.197/32 87.155.159.254 217.6.164.40/31 87.155.159.254 217.6.164.48/29 87.155.159.254 217.6.164.42/32 87.155.159.254 217.6.164.45/32 87
.155.159.254 217.6.164.46/31 87.155.159.254 217.6.167.128/26 87.155.159.254 )


for i in ${array[@]}
 do
  echo $i
done


wenn du zielnetz und mask getrennt haben willst, wirds etwas schwieriger aber das schon mal zum selber testen :)
 
Zuletzt bearbeitet:

bog

Mitglied seit
02.08.2002
Beiträge
10.121
Reaktionen
0
Ort
auf dem mutterschiff
ja, dass die ()-klammern n array anhand von leerzeichen aufsplitten hab ich inzwischen auch rausbekommen. ich frickel grad dran rum, per sed die "netz/mask gw"-kombination um das leerzeichen zu erleichtern (ersetzung mit pipe), um dann in der schleife alle drei wieder auseinanderfriemeln zu koennen (awk vermutlich), aber das will noch nich ganz:
Code:
sroutes=`echo "$sroutes" | sed -e 's/\/(\d+?) (\d+?)/\/\1\|\2/g'`
pienzt wegen ungueltiger backreference \2. benutz ich sed falsch?

e: ach das pattern erkennt er schon nicht. was ueberseh ich da?
e2: ok, die klammern brauchen escapes. nun haengt er wohl an den \d+? dingern. geht mit [:digit:], oder {1,2} bzw {1,3} genausowenig. brrrrrrml?
e3: ok, 's/\/\([[:digit:]]*\) \([[:digit:]]*\)/\/\1|\2/g' funktioniert. in php waer das huebscher gegangen. 8[
 
Zuletzt bearbeitet:

bog

Mitglied seit
02.08.2002
Beiträge
10.121
Reaktionen
0
Ort
auf dem mutterschiff
Code:
sed -r 's/\/\(\d+?\) \(\d+?\)/foo/g'
geht net. wieviel muss man denn bei mengenangaben (+,*) oder zeichen (\d, etc) escapen? kennt sed ueberhaupt das fragezeichen aka ungreedy-modifier?
 
Mitglied seit
15.05.2003
Beiträge
11.307
Reaktionen
8
Ort
Fortuna 1895 Düsseldorf
Code:
sroutes=`echo "$sroutes" | sed -r "s/\s?//g"`

du suchst ja nur nach leezeichen, deshalb kannst du dir das einfangen sparen. berichtige mich wenn ich dich da falsch verstanden habe
 
Zuletzt bearbeitet:

bog

Mitglied seit
02.08.2002
Beiträge
10.121
Reaktionen
0
Ort
auf dem mutterschiff
naja, steht doch schon im ersten posting... ich will die ersten "x.x.x.x/yy z.z.z.z" innerhalb eines schleifendurchlaufes haben. daher muss ich vor dem splitten ins array eben nur das leerzeichen zwischen yy und z.z.z.z rausnehmen, nicht das in "z.z.z.z x2.x2.x2.x2". somit kann ichs mir nicht sparen.
 
Mitglied seit
15.05.2003
Beiträge
11.307
Reaktionen
8
Ort
Fortuna 1895 Düsseldorf
so schnauze voll, nachdem ich ne stunde sed hoch und runter getestet habe, hats genau 2 sminuten für ne perl lösung gebraucht:

echo $sroutes | perl -p -i -e 's/(\d+\/\d+)\s(\d+)/$1$2/g'

der frist natürlich alles an zahlen jetzt mit dem du ihn fütterst aber ich denke du weisst was du tust
 

bog

Mitglied seit
02.08.2002
Beiträge
10.121
Reaktionen
0
Ort
auf dem mutterschiff
fuer die php loesung haett ich 20 sekunden gebraucht :fu:

dummerweise bin ich auf ner embedded plattform unterwegs und hab damit kein perl. und die ip vor dem "/" kannst du dir eigentlich auch sparen, denn mit dessen existenz ist ja gesichert, dass davor eine steht (was anderes wuerde keinen sinn machen).

was ich jetzt als funktionierend, aber fuer mein empfinden sehr unhuebsch habe ist hier im letzten edit beschrieben.
sitze nun noch innerhalb der schleife am schnibbeln mit awk rum. werd dann gleich die loesung reineditieren.
 
Mitglied seit
15.05.2003
Beiträge
11.307
Reaktionen
8
Ort
Fortuna 1895 Düsseldorf
argh augenkrebs ^^ versuch mal den -r operator von sed, damit gehen viele modernen metazeichen wie \d bzw \D oder schön auch \s bzw \S ebenfalls

€ also \s kennt er aber \d irgendwie nicht... doof. egal keinen bock mehr. kisten wo kein perl drauf ist, können niemals linux sein :fu:
 
Zuletzt bearbeitet:

bog

Mitglied seit
02.08.2002
Beiträge
10.121
Reaktionen
0
Ort
auf dem mutterschiff
unix :fu:

die loesung btw zur referenz (huebsch find ichs immernoch nicht, ich nehme verbesserungen gerne an):
Code:
interface=vlan8
SROUTES=193.158.137.14/32 87.155.159.254 87.140.255.0/25 87.155.159.254 87.141.128.0/17 87.155.159.254 193.158.34.0/23 87.155.159.254 194.25.134.197/32 87.155.159.254 217.6.164.40/31 87.155.159.254 217.6.164.48/29 87.155.159.254 217.6.164.42/32 87.155.159.254 217.6.164.45/32 87.155.159.254 217.6.164.46/31 87.155.159.254 217.6.167.128/26 87.155.159.254
# sample werte

SROUTES=`echo $SROUTES | sed -e 's/\/\([[:digit:]]*\) \([[:digit:]]*\)/\/\1|\2/g'`

SRARR=( $SROUTES )

for s in ${SRARR[@]}; do
 echo "$s" | awk '{
  split($1,a,"|");
  split(a[1],b,"/");
  if(b[2]=="32") { ntype="-host" }
  else { ntype="-net" }
  cmd="/sbin/route add " ntype " " a[1] " gw " a[2] " dev '"$interface"'";
  system(cmd);
 }'
done
 
Mitglied seit
02.09.2002
Beiträge
3.281
Reaktionen
106
Alternativvorschlag:

Code:
#!/bin/bash

#193.158.137.14/32 87.155.159.254
#87.140.255.0/25   87.155.159.254
#87.141.128.0/17   87.155.159.254
#193.158.34.0/23   87.155.159.254
#194.25.134.197/32 87.155.159.254
#217.6.164.40/31   87.155.159.254
#217.6.164.48/29   87.155.159.254
#217.6.164.42/32   87.155.159.254
#217.6.164.45/32   87.155.159.254
#217.6.164.46/31   87.155.159.254
#217.6.167.128/26  87.155.159.254

sroutes="193.158.137.14/32 87.155.159.254 87.140.255.0/25 87.155.159.254 87.141.128.0/17 87.155.159.254 193.158.34.0/23 87.155.159.254 194.25.134.197/32 87.155.159.254 217.6.164.40/31 87.155.159.254 217.6.164.48/29 87.155.159.254 217.6.164.42/32 87.155.159.254 217.6.164.45/32 87.155.159.254 217.6.164.46/31 87.155.159.254 217.6.167.128/26 87.155.159.254"


routes=( $sroutes )

i=0
while [[ $i -le ${#routes} ]] ; do
        hostAndMask=${routes[$i]}
        ((i++))
        gw=${routes[$i]}
        ((i++))

        if [[ "${hostAndMask##*/}" == "32" ]] ; then
                echo "/sbin/route add -host ${hostAndMask} gw $gw dev vlan8"
        else
                echo "/sbin/route add -net ${hostAndMask} gw $gw dev vlan8"
        fi
done
 
Mitglied seit
02.09.2002
Beiträge
3.281
Reaktionen
106
Dann probier das Script auf jeden fall vorher nochmal aus, ich bin nämlich nicht sicher, ob ash Dinge wie ((i++)) kann.
 

bog

Mitglied seit
02.08.2002
Beiträge
10.121
Reaktionen
0
Ort
auf dem mutterschiff
hehe ja, zu frueh gefreut. ash kann naemlich gar nix; nicht einmal arrays. habs nun vollstaendig in awk geloest (ordentliche programmiersprache :love:):
Code:
echo "$sroutes" | awk'{
 split($0, a, " ");
 for(i=1; i<=NF/2; i++) {
  cmd="ip route replace " a[2*i-1] " gw " a[2*i] " dev '"$interface"'";
  system(cmd);
 }
}'
noch dazu habe ich naemlich den ip-befehl entdeckt, bei dem man sich das cidr-mask untersuchen sparen kann, UND das auch noch die route bei vorhandensein einfach ersetzt, statt einen fehler (add) auszuspucken.
 
Oben