Seite 1 von 1

Vergleich von zwei Strings in Funktion

Verfasst: 23. Mai 2017, 16:54
von Rumak18
Hallo,
ich habe eine Funktion, mit der ich eine Variable definiere und diese dann weiterführend vergleiche. Leider sagt mir die Linux BASH, dass die Ergebnisse nicht identisch sind. Heißt: Meine Variable "CHECK" ist gleich "1", obwohl ich "0" erwarte. Kann mir Jemand helfen?

Code: Alles auswählen

CHECK_WEB_FUNC()
{
RESULT=$(curl -Is http://www.google.de | head -1)
CORRECT_RESULT="HTTP/1.1 200 OK"
if [[ "$RESULT" == "$CORRECT_RESULT" ]]
then CHECK=0
else CHECK=1
fi
}

[root@localhost~]# CHECK_WEB_FUNC
[root@localhost~]# echo $RESULT
HTTP/1.1 200 OK
[root@localhost~]#echo $CHECK
1


Re: Vergleich von zwei Strings in Funktion

Verfasst: 23. Mai 2017, 17:17
von Gräfin Klara
Das http Protokoll schliesst immer mit \r\n ab, Linux nicht.
Deshalb:

Code: Alles auswählen

RESULT=$(curl -Is http://www.google.de | head -1)
RESULT="${RESULT:0:-1}"
hier der Vergleich
Nicht getestet

Gruß
Gräfin Klara

Re: Vergleich von zwei Strings in Funktion

Verfasst: 23. Mai 2017, 17:57
von abgdf
:thumbs:

Ich hatte dann noch so einen Hackaround gebaut:

Code: Alles auswählen

RESULT=$(echo $RESULT | perl -e '$/="\r\n";while(<>){chomp; print}');
aber Deins ist noch besser.

Re: Vergleich von zwei Strings in Funktion

Verfasst: 24. Mai 2017, 10:30
von Rumak18
Hi,

hmmm... könntet ihr mir das hier erklären?

RESULT="${RESULT:0:-1}"

Re: Vergleich von zwei Strings in Funktion

Verfasst: 24. Mai 2017, 10:45
von marce

Re: Vergleich von zwei Strings in Funktion

Verfasst: 24. Mai 2017, 13:23
von Gräfin Klara
Rumak18 hat geschrieben:
24. Mai 2017, 10:30
Hi,
hmmm... könntet ihr mir das hier erklären?
RESULT="${RESULT:0:-1}"
Ich habe oben geschrieben:
Das http Protokoll schliesst immer mit \r\n ab, Linux macht das nicht.
d.h.
RESULT="$(curl -Is http://www.google.de | head -1)"
Nun ist in "$RESULT" das letzte Zeichen ein '\r'. Deshalb
RESULT="${RESULT:0:-1}"
löscht dieses letzte byte '\r'. Damit entspricht es deinem Vergleich.

Du kannst auch einen Einzeiler schreiben, vielleicht ist der einfacher zu verstehen:
Beispiel:

Code: Alles auswählen

[[ "$(curl -Is http://www.google.de | head -1)" == $'HTTP/1.1 200 OK\r' ]] && echo "Super, alles OK"
Sollte funktionieren

Gruß
Gräfin Klara

Re: Vergleich von zwei Strings in Funktion

Verfasst: 24. Mai 2017, 13:40
von Rumak18
Perfekte Erläuterung. Vielen Dank dafür! Jetzt macht es "Achso" in meinem Kopf
.... Kommando zurück...doch nicht ganz.

Du schreibst :
Das http Protokoll schliesst immer mit \r\n ab, Linux macht das nicht.
d.h.
RESULT="$(curl -Is http://www.google.de | head -1)"
Nun ist in "$RESULT" das letzte Zeichen ein '\r'.
Warum ist bei $RESTULT an dieser Stelle das letzte Zeichen ein "\r" und nicht "\n" wie im ersten Satz beschrieben, da ja bei http ein "\r\n" vorliegt?

Re: Vergleich von zwei Strings in Funktion

Verfasst: 24. Mai 2017, 14:39
von Gräfin Klara
Du liest den string von curl mit /bin/bash
RESULT="$(curl -Is http://www.google.de | head -1)"
und für bash ist - NORMALERWEISE - das Ende des strings bzw. Ende einer Zeile ein '\n'.
Dieses '\n' steht in Wahrheit wohl in "$RESULT" drinnen, wird aber von bash nicht interpretiert.
Änderst du aber dieses Verhalten mit dem Setzen von IFS, dann kann das Ende durchaus ein "\r\n" sein oder schon bei '\r' beendet werden.
Probiere es aus mit
IFS=$'\r'
vor deinem string_vergleich.
Eigentlich sollte bash dann bei '\r' den string splitten bzw. beenden....möglicherweise. Ich bin keine Spezialistin für bash.

Re: Vergleich von zwei Strings in Funktion

Verfasst: 24. Mai 2017, 15:26
von abgdf
Oder Du nutzt doch meine Perl-Zeile, dann weißt Du mit Sicherheit, was Du abschneidest. ;)

Das ist der Vorteil von Perl: Es mag umfangreicher sein als bash, aber es ist leichter zu kontrollieren.
bash ist 'ne alte Zicke. :D

Re: Vergleich von zwei Strings in Funktion

Verfasst: 24. Mai 2017, 22:56
von robi
Vorsicht mit IFS auf Bash-Ebene wenn du nicht ganz genau verstanden hast, was du damit tust, kannst du dir mehr Probleme in die Scripte reinholen als du damit lösen kannst.

Problem ist recht einfach zu verstehen wenn man sich die Zeichenketten mal genauer anschaut.

Code: Alles auswählen

robi@ULTRA-01:~> RESULT=$(curl -Is http://www.google.de | head -1)
robi@ULTRA-01:~> CORRECT_RESULT="HTTP/1.1 200 OK"

robi@ULTRA-01:~> echo $RESULT | hexdump -C
00000000  48 54 54 50 2f 31 2e 31  20 32 30 30 20 4f 4b 0d  |HTTP/1.1 200 OK.|
00000010  0a
Zeichen 16 ist 0x0d; Zeichen 17 ist 0x0a |.|

Code: Alles auswählen

robi@ULTRA-01:~> echo $CORRECT_RESULT | hexdump -C
00000000  48 54 54 50 2f 31 2e 31  20 32 30 30 20 4f 4b 0a  |HTTP/1.1 200 OK.|
00000010 
Zeichen 16 ist 0x0a; Zeichen 17 gibt es nicht.


Der Unterschied ist also ganz klar wie oben schon erwähnt im Zeilenende (Zeilensprung) zu finden, der hier einmal im DOS/Mac Format und einmal im Unix-Format vorliegt.

entweder muss das "0x0d 0x0a" gegen "0x0a" getauscht werden oder das "0x0a" gegen "0x0d 0x0a" um die Strings richtig vergleichen zu können
Wobei man jedoch bedenken muss, das das 0x0a (das Ende der Zeile) schon nicht mehr Bestandteil des Strings ist und in der Variable auch nicht vorhanden ist.

Möglichkeiten gibt es ganz viele., hier mal ein paar in der Pipe geschrieben, hexdump am ende, damit man besser sieht was genau passiert.

Code: Alles auswählen

Bash       :  (Beispiel schon oben genannt.)  ${RESULT:0:-1}                 (Bedeutet: Ausschnitt 1. bis Vorletztes Zeichen)
           :  echo ${RESULT%?}  | hexdump -C                               #letztes Zeichen wegschneiden
tr         :  echo $RESULT | tr -d "\r" | hexdump -C   
cut        :  echo $RESULT | cut -d $(echo -en "\r")  -f 1 | hexdump -C  
sed        :  echo $RESULT | sed 's/\r//g' | hexdump -C                     # 0x0d wird weggeschnitten
           :  echo $RESULT | sed 's/\(.*\)./\1/'| hexdump -C                  # letztes Zeichen wird weggeschnitten
awk        :  echo $RESULT | awk '{gsub(/\r/,"");print}' | hexdump -C
dos2unix   :  echo $RESULT | dos2unix | hexdump -C
......
Anderes herum geht das genauso, eben am Ende noch ein "\r" Anhängen oder unix2dos konvertieren.
Das macht sich auch ganz gut gleich bei der Erstellung der Variable zu erledigen. zB.

Code: Alles auswählen

CORRECT_RESULT=$(echo -e "HTTP/1.1 200 OK\r")
Dann kann man sich im Scriptverlauf sparen die ganzen Ergebnisse jedesmal erst noch umwandeln zu müssen.

robi

Re: Vergleich von zwei Strings in Funktion

Verfasst: 29. Mai 2017, 14:36
von Rumak18
Ok. Nun verstanden...mir war nicht klar, dass die BASH ein "Carriage Return" liefert. Ich dachte, die BASH liefert einen "Line Feed".

Re: Vergleich von zwei Strings in Funktion

Verfasst: 29. Mai 2017, 22:02
von framp
Es ist nicht die bash die ein CRLF liefert sondern der HTTP Stream ;)

Re: Vergleich von zwei Strings in Funktion

Verfasst: 30. Mai 2017, 10:50
von Rumak18
Hi framp,

ja, verstehe. HTTP leifert CRLF, aber die BASH liefert "\r" korrekt?