[BASH] sed erkennt Zeile in einer Datei nicht

Krik

Fleet Admiral
Registriert
Juni 2005
Beiträge
14.444
Moin,

ich habe diesen Code. Er soll ein Backup einer Datei erstellen, anschließend darin ein paar Zeilen ändern und schließlich noch ein Programm aufrufen.

Alles geht, bis auf die Zeilen ändern. Warum? Was ist an der Regex falsch?

Code:
#!/bin/sh

FILE="/etc/sysctl.conf"
BAKFILE="$FILE.bak-`date +%y%m%d%H%H%S`"

echo -n "Processing $FILE: "

# Existiert die Datei?
if [ -f "$FILE" ] ; then

        # Backup
        echo -n "Backing up"
        cp --remove-destination --preserve "$FILE" "$BAKFILE"

        # Modifizieren
        echo -n ", modifying"
        sed -n 's/net.ipv4.ip_forward\s*=\s*0\s*/\nnet.ipv4.ip_forward = 1\n/g' "$FILE"
        sed -n 's/net.ipv4.conf.all.rp_filter\s*=\s*0\s*/\nnet.ipv4.conf.all.rp_filter = 1\n/' "$FILE"
        sed -n 's/kernel.sysrq\s*=\s*1\s*/\nkernel.sysrq = 0\n/' "$FILE"

        # Kernelparameter aktualisieren lassen
        echo -n ", reloading sysctl"
        sysctl -p > /dev/null

        echo ", done."
else
        # Fehlermeldung
        echo "Error! Not Found!"
        echo "Make sure these kernel parameters are set:"
        echo "\tnet.ipv4.ip_forward = 1"
        echo "\tnet.ipv4.conf.all.rp_filter = 1"
        echo "\tkernel.sysrq = 0"
fi
Die Regex ist so gestaltet, dass sie beliebig viele Leerzeichen zwischen Text und =, und zwischen Text und Ende zulässt. Man weiß ja nie, was man im System so vorfindet und ob schon jemand per Hand dort rumgepfuscht hat.

Bei dem Kommandozeilenbeispiel echo "Das ist nur eine Zeile ..." | sed 's/nur\s*eine/nur eine volle/' funktioniert es blendend. Übertragen auf das Skript geht es aber nicht.

Ich bin hier ratlos. Weiß jemand, an welcher Stelle und warum es schief geht?
Gruß, Laurin
 
sed liest einen Eingabestream (stdin) und schreibt einen Ausgabestream (stdout). Statt stdin kann auch eine Eingabedatei verarbeitet werden. Die Ausgabe wird trotzdem nach stdout geschrieben. Du musst also die Ausgabe in eine Datei umleiten. Geschickterweise nicht in die gerade gelesene Eingabedatei.
 
Nur daran soll es liegen? Oh Mann! Ok, danke für deinen Tipp, ich probiere es nach her aus.

Edit: Danke, es hat jetzt funktioniert.
Das hier habe ich verwendet:
Code:
        sed -c -i "s/\(net.ipv4.ip_forward\s*=\s*\).*/\11/g" $FILE
        sed -c -i "s/\(net.ipv4.conf.all.rp_filter\s*=\s*\).*/\11/g" $FILE
        sed -c -i "s/\(kernel.sysrq\s*=\s*\).*/\10/g" $FILE

Ich habe noch eine Frage:
Wenn die gesuchte Zeile nicht vorkommt, also der Parameter überhaupt nicht in der Datei steht, dann muss er ihr hinzugefügt werden. Kann man das irgendwie in sed mit umsetzen?
Da jetzt extra noch etwas wie if [ (cat "$FILE" | grep "net.ipv4.ip_forward = 1" | wc -l) -le 0 ] ; then echo "net.ipv4.ip_forward = 1" > "$FILE" fi hinterher hängen, ist irgendwie doof. ^^
 
Zuletzt bearbeitet:
Zurück
Oben