ubuntuusers.de

sed: Datei über bash-Skript bearbeiten

Status: Gelöst | Ubuntu-Version: Server 10.04 (Lucid Lynx)
Antworten |

scjunkie

Anmeldungsdatum:
7. Februar 2010

Beiträge: 15

Hallo~~~

ich schreibe ein Skript, das die Datei /etc/network/interfaces bearbeiten kann.

Das Skript soll die statische Adresse des Interfaces Null herauslöschen (mehrere Zeilen) dann auf dhcp wechseln.

cat /etc/network/interfaces | head -n 9 > tempfile
cat /etc/network/interfaces | tail -n 10 >> tempfile

sed '/eth0/ a\
iface eth0 inet dhcp' tempfile > /etc/network/interfaces

Das funktioniert auch soweit gut. Das Skript ist aber zeilenabhängig und wenn jmd. das Skript manuell bearbeiten würde,

könnte es sein, dass das ganze nicht mehr funktioniert!

Es muss eine bessere Lösung geben aber da ich mich mit sed nicht gut auskenne, komme ich einfach nicht drauf.

Welche sed-Funktion müsste ich hier verwenden?

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17607

Wohnort: Berlin

Sich von sed lösen, und 2 Dateien machen,

  • interfaces.static und

  • interfaces.dhcp,

und bei Bedarf das eine oder das andere nach interfaces kopieren.

Oder was spricht dagegen?

scjunkie

(Themenstarter)

Anmeldungsdatum:
7. Februar 2010

Beiträge: 15

Das könnte man schon machen.

Dagegen spricht aber, dass die Methode die andere Änderungen wie z.B. an eth1 einfach überschreibt.

Ich würde es gerne so haben, dass die Datei beliebig manuell bearbeitet werden kann und dass die Änderungen bestehen bleibt.

Daher dachte ich die Mustererkennung von sed wäre hier richtig.

Oder gibt es andere Alternative?

elektronenblitz63

Avatar von elektronenblitz63

Anmeldungsdatum:
16. Januar 2007

Beiträge: 29307

Wohnort: NRW

Hallo,
warum umständlich die interfaces ändern? Da werden sich wahrscheinlich schnell Fehler einschleichen. Sofern man möchte, können die benötigten Schnittstellen vorkonfiguriert werden, muss aber nicht:

iface lo inet loopback
auto lo

iface eth0 inet manual
iface eth1 inet manual
usw.

Aufruf mit statischer und automatischer Konfiguration:

/sbin/ifconfig $iface $address broadcast $broadcast netmask $netmask
/sbin/dhclient $iface

Bei statischer Konfiguration muss dann ggf. noch der DNS manuell gesetzt werden. Kommt darauf an wozu das alles benötigt wird.

Das kann man natürlich auch direkt in ein Skript verpacken und mit entsprechenden Optionen aufrufen. Bei Systemstart aut. z.B. über rc.local.

Ein Beispiel was man alles so machen kann.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17607

Wohnort: Berlin

Nicht, um elektronenblitz63 zu widersprechen, sondern um zu zeigen, wie es mit sed ginge - ich dachte ich hätte es die Nacht schon gepostet, aber offenbar habe ich vergessen abzuschicken - also mit sed ginge es so:

sudo sed -i '/eth0/d;$iface eth0 inet dhcp/' /etc/network/interfaces

Aber wahrscheinlich hat elektronenblitz63 Recht.

elektronenblitz63

Avatar von elektronenblitz63

Anmeldungsdatum:
16. Januar 2007

Beiträge: 29307

Wohnort: NRW

user unknown schrieb:

Nicht, um elektronenblitz63 zu widersprechen ...

Kein Thema, mich interessiert was damit bezweckt werden soll. Eine Änderung der interfaces wirkt sich zunächst nur nach einem Netzwerk-Restart aus. Ist die interfaces fehlerhaft, hat man ein Problem und muss die Datei sowieso editieren.

scjunkie

(Themenstarter)

Anmeldungsdatum:
7. Februar 2010

Beiträge: 15

Danke erstmal für die Antworten! 👍

Ich habe mit ufdbGuard und Shalla's List einen URL-Filter aufgebaut.

Dazu wollte ich mit Bash-Skript und dialog(GUI) das Ganze vereinfachen, sodass auch Anfänger die sich mit Linux nicht gut auskennen damit was anfangen können.

Die Benutzer sollen dabei auch die Konfigurationsmöglichkeit bekommen, die Schnittstellen per GUI zu verändern. Daher die Veränderung der Datei interfaces.

ifconfig wollte ich eigentlich nicht verwenden weil die Veränderung nach dem Reboot wieder weg ist. Aber wie elektronenblitz63 sagt, wenn die Lösung mit sed zu Problemen führt, werde ich die Methode mit ifconfig in Verbindung mit local.rc vorziehen.

@user unknown

sudo sed -i '/eth0/d;$iface eth0 inet dhcp/' /etc/network/interfaces

Bei mir scheint die Lösung nicht zu funktionieren.

Diese Zeile löscht die Zeilen wo eth0 drinne steht und fügt die Zeile "$iface eth0 inet dhcp" hinzu oder?

Damit sind doch die anderen Adressen wie netmask und gateway nicht gelöscht. Oder mache ich da was falsch?...

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17607

Wohnort: Berlin

scjunkie schrieb:

@user unknown

sudo sed -i '/eth0/d;$iface eth0 inet dhcp/' /etc/network/interfaces

Bei mir scheint die Lösung nicht zu funktionieren.

Diese Zeile löscht die Zeilen wo eth0 drinne steht und fügt die Zeile "$iface eth0 inet dhcp" hinzu oder?

Damit sind doch die anderen Adressen wie netmask und gateway nicht gelöscht. Oder mache ich da was falsch?...

Also sudo und -i kann man weglassen, und so ausprobieren, was passieren würde. Allerdings hat sich ein Fehler eingeschlichen, es muss $aiface heißen, nicht $iface. Oder $iiface.

sed '/eth0/d;$aiface eth0 inet dhcp/' /etc/network/interfaces

a wie append, oder i wie insert. Und $ steht, so verwendet, für das Ende der Datei (sonst oft für Zeilenende). /eth0/d löscht alle Zeilen, die die Zeichenkette eth0 enthalten.

Von netmask und gateway war zuvor nicht die Rede - ich habe keine Glaskugel um zu sehen, wie Deine interfaces-Datei vorher aussah.

Wenn Du aber zeigst, wie es vorher aussieht, und wie es nachher aussehen soll, schaue ich gerne nochmal.

scjunkie

(Themenstarter)

Anmeldungsdatum:
7. Februar 2010

Beiträge: 15

Es funktioniert noch nicht. Liegt wahrscheinlich daran, dass du meine interfaces-Datei nicht kennst. Hier meine interfaces-Datei.

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.2.2
netmask 255.255.255.0
gateway 192.168.2.1

auto eth1
iface eth1 inet static
address 192.168.10.1
netmask 255.255.255.0
broadcast 192.168.10.255

up /etc/init.d/dnsmasq restart
up sysctl -w net.ipv4.ip_forward=1

So soll die Datei nach sed aussehen.

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
address 192.168.10.1
netmask 255.255.255.0
broadcast 192.168.10.255

up /etc/init.d/dnsmasq restart
up sysctl -w net.ipv4.ip_forward=1

Danke im voraus.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17607

Wohnort: Berlin

cat interfaces | sed '/eth0/,/^$/d;/auto eth1/iauto eth0\niface eth0 inet dhcp\n'

Das sind 2 Befehle, per Semikolon getrennt.

  • a) Vom Muster eth0 bis ^$, also leere Zeile, delete.

  • b) Beim Muster auto eth1 insert diese drei Zeilen (\n ist ein Zeilenumbruch).

alternativ:

cat interfaces | sed '/eth0/,+3d;/auto eth1/iauto eth0\niface eth0 inet dhcp\n'

Komma +3 d bedeutet +3 folgende Zeilen: delete.

Führst Du das 2. Kommando 2x hintereinander auf die Datei aus, dann sieht das Ergebnis aber problematisch aus. Also ist die Leerzeilenerkennung etwas robuster.

scjunkie

(Themenstarter)

Anmeldungsdatum:
7. Februar 2010

Beiträge: 15

Wow. Was man so alles mit sed erreichen kann!!

Vielen Dank! Funktioniert einwandfrei. 😊

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Mit dem sed '/eth0/,+3d; ... wäre ich auch sehr vorsichtig. Sonst passiert genau das was elektronenblitz63 angemahnt hat: Du schreibst die Datei kaputt.

Denn wenn dort bereits die iface eth0 inet dhcp - Version drin steht, dann löscht er ja auch die 1.Zeile des nächsten Blocks !
(überhaupt ist die Anzahl Zeilen nicht unbedingt konstant)

Wenn schon überhaupt mit sed, dann auf jeden Fall entweder die 1. Version von user unknown
(die überflüssigen address / netmask / gateway - Zeilen machen nämlich nichts aus)
- oder mit einem sed-Filter, der spätestens bei der Leerzeile aufhört zu löschen. Also so:

sed '/eth0$/iauto eth0\niface eth0 inet dhcp\n 
/eth0$/,/^$/d'  /etc/network/interfaces

Das eth0$ muss unbedingt mit drinstehen, denn manchmal (z.B. bei mir) gibt es weitere Schnittstellen wie eth0:0 und die macht er sonst mit platt. Außerdem gibt es ja nicht immer ein Interface eth1 ...
Und ja, der Zeilenumbruch ist nötig, damit der i-Befehl weiß wo er zu Ende ist.

LG,

track

scjunkie

(Themenstarter)

Anmeldungsdatum:
7. Februar 2010

Beiträge: 15

Danke für die Tipps. Das macht das Skript viel robuster!

Dann markier ich mal den Threat als gelöst. ☺

Antworten |