ubuntuusers.de

Linux Bash: Kampf mit " und ' (und Sonderzeichen)

Status: Ungelöst | Ubuntu-Version: Xubuntu 20.04 (Focal Fossa)
Antworten |

Umaash

(Themenstarter)

Anmeldungsdatum:
7. Juni 2016

Beiträge: 123

Das sieht interessant aus. Danke für das Beispiel.

Umaash

(Themenstarter)

Anmeldungsdatum:
7. Juni 2016

Beiträge: 123

Ich bin inzwischen ziemlich weit fortgeschritten mit dem Programm.

Hier ist eine Variante mit "sed".

Dieses Programm löscht (im aktuellen Entwicklungsstadium) einen Zeilenblock aus verschiedenen Konfigurationsdateien die auf /etc/ oder an einem anderen Platz in "/" liegen. Was gelöscht werden soll, steht in einer separaten Datei mit dem Namen "Aenderungsprotokoll.txt".

Wichtig ist mir wie auch in Post #1 geschrieben, dass durch alle Verarbeitungs-Operationen weder der Inhalt der Konfigurationsdateien (aus denen etwas gelöscht werden soll), noch der Zeilenblock, der gelöscht werden soll und aus der Datei "Aenderungsprotokoll.txt" stammt, verändert wird.

Denn wenn der Zeilenblock, der aus der Datei "Aenderungsprotokoll.txt" stammt, verändert wird durch eine Operation, dann wird er nicht mehr in der Konfigurationsdatei gefunden werden und dann funktioniert das Programm nicht. Wenn die Konfigurationsdatei, aus der gelöscht werden soll, verändert wird (natürlich ausser dem Löschen), dann funktioniert Linux nicht mehr richtig.

Zuerst der Inhalt der Datei "Aenderungsprotokoll.txt" (Ich habe mir noch nicht die Mühe gemacht, die Protokolldatei mit realen Inhalten zu befüllen, deshalb machen Zeilen wie "aaa" oder "bbb" nicht viel Sinn, aber einige demonstrieren, dass es mir wichtig ist, dass auch Sonderzeichen oder Sonderzeichen Kombinationen, die manchmal als Befehle interpretiert werden können, nicht verändert werden dürfen. Sonderzeichen Kombinationen, die manchmal als Befehle interpretiert werden können, dürfen natürlich auch nicht zu Fehlern beim Verarbeiten des Codes führen. Die Frage ist: Und machen das die Schlüsselcode-Zeilen wirklich nicht?):

Aenderungsprotokoll:

-Datei:
/etc/environment
-löschen:
g.h"f*$g"fd'd/f#@%q\n&='f\g\\//==?+[]{|()^`n`r`a\d,\s\w\t\r\p{xx}f><~b\s\S\w\	W
ccc
aaa

-Datei:
/etc/DateiX1
-löschen:
bbb
ccc


-Datei:
/etc/DateiX2
-einfügen nach:
eeeeeennnnnn
-einzufügende Zeilen:
ZZZZZZ

-Datei:
/etc/DateiX4
-ersetzten:
eeeeeeeeeeer
-durch:
ddddddu
hhhz$k

Und hier ist der Code:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/bin/bash

# Dateipfad zur Config-Datei
config_file="Aenderungsprotokoll.txt"

# Variable für den gesamten Inhalt
config_content=""

# Schleife, um die Config-Datei zeilenweise zu durchlaufen
while IFS= read -r line; do

	if [[ "$line" == "-Datei:" || "$line" == "-löschen:" || "$line" == "-einfügen nach:" || "$line" == "-einzufügende Zeilen:" || "$line" == "-ersetzten:" || "$line" 	== "-durch:" || "$line" == "-ignoriere:" ]]; then
    UnterabschnittImAenderungsprotokoll=""
	fi

#Abschnitt für die Inhalte unter den Überschriften	
	if [ "$UnterabschnittImAenderungsprotokoll" == "Dat" ]; then
		DateinamenArrey[$ZahlerFurDateiUndArray]=$line
		UnterabschnittImAenderungsprotokoll=""
	fi
	
	case "$UnterabschnittImAenderungsprotokoll" in
    "loesch"|"einf_nach"|"ersetz")
        if [ -z "${ZeilenAktion1Arrey[$ZahlerFurDateiUndArray]}" ]; then      
        	ZeilenAktion1Arrey[$ZahlerFurDateiUndArray]=$(echo "$line" | fold -w1 | sed 's/\(.\)/[\1]/g' | tr -d '\n')        
		else #Dem Array wird nur ein Zeilenumbruch hinzugefègt, wenn es nicht leer ist. Am Anfang ist es lehr. Erst nachdem die erste Zeile hinzugefègt wurde ist es nicht mehr leer
			ZeilenAktion1Arrey[$ZahlerFurDateiUndArray]+='\n'$(echo "$line" | fold -w1 | sed 's/\(.\)/[\1]/g' | tr -d '\n')  	
		fi
        ;;
        
	"einzufügen"|"durch")
		if [ -z "${ZeilenAktion2Arrey[$ZahlerFurDateiUndArray]}" ]; then
			ZeilenAktion2Arrey[$ZahlerFurDateiUndArray]="$line"
		else
			ZeilenAktion2Arrey[$ZahlerFurDateiUndArray]+=$'\n'"$line" #Dem Array wird nur ein Zeilenumbruch hinzugefègt, wenn es nicht leer ist.
		fi
        ;;
esac

	
#Abschnitt für die Erfassung der Überschriften
	if [ "$line" == "-ignoriere:" ]; then
    	IgnorierenODERnicht[((ZahlerFurDateiUndArray + 1))]=$line
    fi	
	if [ "$line" == "-Datei:" ]; then
    	((ZahlerFurDateiUndArray++))
    	UnterabschnittImAenderungsprotokoll="Dat"
	fi
	if [ "$line" == "-löschen:" ]; then
    	NameAktion1Arrey[$ZahlerFurDateiUndArray]=$line
    	UnterabschnittImAenderungsprotokoll="loesch"
    fi
    if [ "$line" == "-einfügen nach:" ]; then
    	NameAktion1Arrey[$ZahlerFurDateiUndArray]=$line
    	UnterabschnittImAenderungsprotokoll="einf_nach"
    fi
    if [ "$line" == "-einzufügende Zeilen:" ]; then
    	NameAktion2Arrey[$ZahlerFurDateiUndArray]=$line
    	UnterabschnittImAenderungsprotokoll="einzufügen"
    fi
    if [ "$line" == "-ersetzten:" ]; then
    	NameAktion1Arrey[$ZahlerFurDateiUndArray]=$line
    	UnterabschnittImAenderungsprotokoll="ersetz"
    fi
    if [ "$line" == "-durch:" ]; then
    	NameAktion2Arrey[$ZahlerFurDateiUndArray]=$line
    	UnterabschnittImAenderungsprotokoll="durch"
    fi
	
    # Hier können Sie Ihre Bedingungen für die Zeilenprüfung einfügen
    # In diesem Beispiel überprüfen wir, ob die Zeile das Wort "Option" enthält
    #if [[ "$line" == *"Option"* ]]; then
        # Hier können Sie den Inhalt der Zeile der Variablen zuweisen oder andere Aktionen durchführen
        config_content="$config_content$line\n"
    #fi
done < "$config_file"




# Kontrolle der erfassten ÄnechoEditRootDateienderungen:
echo "${DateinamenArrey[@]}"
echo "${NameAktion1Arrey[@]}"
echo "${ZeilenAktion1Arrey[@]}" #Das Leerzeichen ist nicht im Aarey selber drin, sondern wird wohl durch den Befehl "echo" erzeugt
echo "${NameAktion2Arrey[@]}"
echo "${ZeilenAktion2Arrey[@]}"
echo "${IgnorierenODERnicht[@]}"
echo "$ZahlerFurDateiUndArray"


##### Teil 2 Änderung der Dateien ############

# Anzahl Dateien, die bearbeitet werden muessen
AnzahlDateien=${#DateinamenArrey[@]}

	# Schleife über die Arrays, beginnend ab Index 1
	for ((i=1; i<=$AnzahlDateien; i++)); do
	
	# Überprüfen, ob die Datei existiert
        if [ -f "${DateinamenArrey[i]}" ]; then
	
		# Überprüfen, ob "-löschen:" im Array NameAktion1Arrey vorhanden ist
    	if [[ "${NameAktion1Arrey[i]}" == "-löschen:" ]]; then
 			#Dafür sorgen, dass es am Schluss nur einen "\n" hat
			ZeilenAktion1Arrey[i]=$(echo -n "${ZeilenAktion1Arrey[i]}" | sed -e ':a' -e 's/\\n\\n$/\\n/;ta')   	
    		#Hier wird die Löschung durchgeführt (zum Debugging nur in eine Datei)
			ZeilenAktion1Arrey[i]=$(sed ":a;N;\$!ba;s/${ZeilenAktion1Arrey[i]}//g" "${DateinamenArrey[i]}")
			echo "${ZeilenAktion1Arrey[i]}"

		fi
			
		else
            echo "Die Datei ${DateinamenArrey[i]} existiert nicht."
        fi
	done

Schlüsselzeilen, wo Verarbeitungsoperationen auftreten sind wohl die folgenden:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
while IFS= read -r line; do

ZeilenAktion1Arrey[$ZahlerFurDateiUndArray]=$(echo "$line" | fold -w1 | sed 's/\(.\)/[\1]/g' | tr -d '\n') 

ZeilenAktion1Arrey[$ZahlerFurDateiUndArray]+='\n'$(echo "$line" | fold -w1 | sed 's/\(.\)/[\1]/g' | tr -d '\n')  

ZeilenAktion1Arrey[i]=$(echo -n "${ZeilenAktion1Arrey[i]}" | sed -e ':a' -e 's/\\n\\n$/\\n/;ta')   	

ZeilenAktion1Arrey[i]=$(sed ":a;N;\$!ba;s/${ZeilenAktion1Arrey[i]}//g" "${DateinamenArrey[i]}")
			echo "${ZeilenAktion1Arrey[i]}"

Der Code funktioniert. Aber ist er so geschrieben, dass er nicht durch Befehle oder Sonderzeichen, die als Befehle interpretiert werden könnten Fehler produzieren würde?

Und wird durch die Verarbeitungsoperation wirklich gar nie etwas verändert, was nicht verändert werden sollte?

Antworten würden mich freuen. Besten Dank.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11233

Wohnort: München

Wenn ich das richtig sehe, hast du dir eine Art eval nachgebaut, indem du die Ausgabe von echo in einer Subshell verarbeitest - damit können (un)absichtlich problematische Eingaben Dinge ausführen, die man nicht unbedingt haben will - https://www.baeldung.com/linux/bash-safe-use-eval hat ein paar Ansätze, wie man das Problem etwas abmildern kann.

Antworten |