Mit Shellbefehl Key=Wert Paar auslesen?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Cordess
Beiträge: 189
Registriert: 09.01.2006 00:37:22

Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von Cordess » 01.08.2021 21:05:06

Was ist der einfachste Weg in einer Bash eine Datei mit Key Werte Paaren auszulesen und einen bestimmten Wert auszugeben?

Konkret möchte ich mir den Codenamen der Debian Version aus der Datei /etc/os-release ausgeben lassen.
Bevor ich mir jetzt aber was mit cat, awk und grep bastel, wollte ich wissen, ob es für Key Werte Paare eine elegantere Methode gibt.
Der Inhalt der gesamten Datei liegt nämlich als Key Werte Paar vor.

Bspw. für Debian 10 Buster:

Code: Alles auswählen

$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
Brauchen tue ich davon also VERSION_CODENAME=buster ohne VERSION_CODENAME= in einem String.
Das ganze, also der String "buster" soll in einem Shell Script weiterbenutzt werden.

JTH
Moderator
Beiträge: 1277
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von JTH » 01.08.2021 21:11:35

Die Datei ist darauf ausgelegt (nehme ich vom Format her zumindest sehr stark an), dass du sie in einer Shell sourcen[1, 2] kannst. Damit geht das ganz einfach:

Code: Alles auswählen

#!/bin/sh

. /etc/os-release

echo "$VERSION_CODENAME"
[1] https://www.gnu.org/software/bash/manua ... ndex-_002e
[2] https://tldp.org/LDP/abs/html/internal.html#SOURCEREF
Manchmal bekannt als Just (another) Terminal Hacker :D

Cordess
Beiträge: 189
Registriert: 09.01.2006 00:37:22

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von Cordess » 01.08.2021 21:17:35

Danke, wie sicher ist denn das sourcen?

In folgendem stackoverflow Kommentar habe ich dazu folgendes gefunden:
Sourcing the file using . or source has the problem that you can also put commands in there that are executed. If the input is not absolutely trusted, that's a problem (hello rm -rf /).
https://stackoverflow.com/questions/499 ... rom-a-file

Also sollte man das vielleicht doch besser nicht verwenden, oder?

Als klassische Lösung habe ich jetzt folgendes:

Code: Alles auswählen

grep VERSION_CODENAME /etc/os-release | awk -F= '{print $2}'
Aber vielleicht geht das noch eleganter?

inne
Beiträge: 2872
Registriert: 29.06.2013 17:32:10
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von inne » 01.08.2021 21:26:55

Hallo,

Code: Alles auswählen

grep VERSION_CODENAME /etc/os-release | awk -F= '{print $2}'
Aber vielleicht geht das noch eleganter?
Vlt. gefällt es dir so besser (Das habe ich mal auf geschnappt :THX: ):

Code: Alles auswählen

$ sed -n -E "/^VERSION_CODENAME=/{s///;p}"
bullseye
PS: Ich könnte mir aber vorstellen das Dateien wie /etc/os-release, unter Linux, zum includen mit source gemacht sind. Aber da würde ich den Paketbetreuer/Upstream mal deswegen anschreiben vorher.
$ dpkg -S /etc/os-release
base-files: /etc/os-release
(=_=)

Für das Volk kommt das Essen dem Himmel gleich! (Mandat des Himmels)

Benutzeravatar
Meillo
Moderator
Beiträge: 6790
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von Meillo » 01.08.2021 21:37:22

Cordess hat geschrieben: ↑ zum Beitrag ↑
01.08.2021 21:17:35
Danke, wie sicher ist denn das sourcen?

In folgendem stackoverflow Kommentar habe ich dazu folgendes gefunden:
Sourcing the file using . or source has the problem that you can also put commands in there that are executed. If the input is not absolutely trusted, that's a problem (hello rm -rf /).
https://stackoverflow.com/questions/499 ... rom-a-file

Also sollte man das vielleicht doch besser nicht verwenden, oder?
Im Fall von der Datei sollte das kein relevantes Problem sein, da sie von Debian kontrolliert wird und die koennen dir eh beliebigen Code unterschieben. Deiner Distribution musst du also sowieso vertrauen.
Als klassische Lösung habe ich jetzt folgendes:

Code: Alles auswählen

grep VERSION_CODENAME /etc/os-release | awk -F= '{print $2}'
Aber vielleicht geht das noch eleganter?
Ohne grep (und etwas exakter, weil es auch mit "VERSION" funktioniert) so:

Code: Alles auswählen

awk -F= '$1=="VERSION_CODENAME"{print $2}' /etc/os-release
So wuerde ich das machen.
Use ed(1) once in a while!

JTH
Moderator
Beiträge: 1277
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von JTH » 01.08.2021 21:38:02

Cordess hat geschrieben: ↑ zum Beitrag ↑
01.08.2021 21:17:35
Danke, wie sicher ist denn das sourcen?
Prinzipiell kannst du darüber beliebigen Shellcode ausführen, das stimmt wohl. Es wird aber an allen möglichen Stellen verwendet, z.B. von deiner ~/.bashrc, ~/.profile, /usr/share/bash-completion/bash_completion (das liest sogar Dateien aus deinem $HOME) uvvvvvm. /usr/bin/lsb_release z.B. sourced sogar konkret /etc/os-release.

Unabhängig davon: Wer auf deinem System die Möglichkeit hatte, die /etc/os-release zu bearbeiten (bzw. /usr/lib/os-release, /etc/os-release ist nur ein Symlink), hatte schon root-Rechte und konnte dein System daher beliebig beschädigen.

Wenn du dem also an dieser Stelle nicht traust, solltest du ganz schnell den Stecker von deinem Rechner ziehen ;)
Manchmal bekannt als Just (another) Terminal Hacker :D

Cordess
Beiträge: 189
Registriert: 09.01.2006 00:37:22

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von Cordess » 01.08.2021 21:47:34

Danke euch allen. :THX:


Ich werde jetzt die Variante von Meillo nehmen, da sie relativ flexibel ist und sich auch für Dateien eignet, der ich nicht zwingend vertrauen muss. In dem Fall wäre das zwar nicht so wichtig, da ihr wie ihr selbst sagt, os-release von Debian selbst ist, aber so kann ich das jederzeit mal auch für andere Scripte nutzen.
Und die sed Lösung würde zwar auch gehen, aber sed mag ich nicht besonders, da sed für mich recht kryptisch ist und man dann wieder nachschauen muss, was welches Zeichen in sed macht. Awk finde ich da einfacher, da intuitiver.

Also nehme ich diese hier:
Meillo hat geschrieben: ↑ zum Beitrag ↑
01.08.2021 21:37:22
Ohne grep (und etwas exakter, weil es auch mit "VERSION" funktioniert) so:

Code: Alles auswählen

awk -F= '$1=="VERSION_CODENAME"{print $2}' /etc/os-release

JTH
Moderator
Beiträge: 1277
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von JTH » 01.08.2021 21:59:19

Meillo hat geschrieben: ↑ zum Beitrag ↑
01.08.2021 21:37:22

Code: Alles auswählen

awk -F= '$1=="VERSION_CODENAME"{print $2}' /etc/os-release
So wuerde ich das machen.
Ist das heut Abend ein Duell zwischen awk und Shellbuiltins? :wink:
Manchmal bekannt als Just (another) Terminal Hacker :D

Benutzeravatar
Meillo
Moderator
Beiträge: 6790
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von Meillo » 01.08.2021 22:25:42

JTH hat geschrieben: ↑ zum Beitrag ↑
01.08.2021 21:59:19
Ist das heut Abend ein Duell zwischen awk und Shellbuiltins? :wink:
Dann steht's jetzt 1:1. ;-) ... dabei haette ich selber die Loesungen in den zwei Threads gerade andersrum bewertet. Hier haette ich die Datei (in einer Subshell bzw. einem Script) gesourct und im anderen Thread habe ich mein awk-Script echt gut gefunden.

Ich freue mich einfach, dass es wieder solche kleinen Scriptingproblemchen gibt, die mir oft in awk Spass machen. Auch wenn ich gerne mit Sportsgeist scripte, so bereitet mir es auch einfach so schon viel Freude ... und noch viel mehr wenn man dabei nicht Alleinunterhalter ist. ;-) :THX:
Use ed(1) once in a while!

inne
Beiträge: 2872
Registriert: 29.06.2013 17:32:10
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von inne » 01.08.2021 22:30:42

Cordess hat geschrieben: ↑ zum Beitrag ↑
01.08.2021 21:47:34
Und die sed Lösung würde zwar auch gehen, aber sed mag ich nicht besonders, da sed für mich recht kryptisch ist und man dann wieder nachschauen muss, was welches Zeichen in sed macht. Awk finde ich da einfacher, da intuitiver.
Das p steht für Print
https://www.grymoire.com/Unix/Sed.html#uh-9
https://www.grymoire.com/Unix/Sed.html#uh-15b

Die Klammern Gruppieren
https://www.grymoire.com/Unix/Sed.html#uh-35

Und was ich dort nun nicht gefunden habe, aber es steht bestimmt auch dort:
Das leere s// (s=Substitution=Ersetzung) hat als Vorgabewert den Match: echo MATCH=ABC | sed '/^MATCH=/s///'

PS: Auswendig konnte ich diesen Fall aber auch nicht :mrgreen:
(=_=)

Für das Volk kommt das Essen dem Himmel gleich! (Mandat des Himmels)

tobo
Beiträge: 1063
Registriert: 10.12.2008 10:51:41

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von tobo » 02.08.2021 01:56:39

inne hat geschrieben: ↑ zum Beitrag ↑
01.08.2021 21:26:55
Vlt. gefällt es dir so besser (Das habe ich mal auf geschnappt :THX: ):

Code: Alles auswählen

$ sed -n -E "/^VERSION_CODENAME=/{s///;p}"
bullseye
3 kurze Anmerkungen dazu: 1. verwendest du keine erweiterten regulären Ausdrücke, somit ist der Optionsschalter dazu (-E) überflüssig. 2. sollte jeder Befehl in der Klammerung mit Semikolon abgeschlossen werden. Zumindest dann, wenn der Code außerhalb des GNU-Universums funktionieren soll. Und 3. kannst du das p auch als Flag zur Sustitution angeben und damit die Klammerung generell überflüssig machen.

inne
Beiträge: 2872
Registriert: 29.06.2013 17:32:10
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von inne » 02.08.2021 11:02:10

Du hast recht, ich hatte das nur aus einem Skript hier copy und paste eingefügt. Und z.B. das -E kopiere ich einfach immer mit, *mich* stört das nicht. Habe das auch in meinen Aliases gesetzt z.B.
Es stört ja nicht? Mit dem das es außerhalb des GNU-Universums nicht tut, hast du aber recht. Dass ist nicht so schön und war mir so nicht bewusst.

Code: Alles auswählen

$ sed -n "/^VERSION_CODENAME=/s///p" /etc/os-release
bullseye
(=_=)

Für das Volk kommt das Essen dem Himmel gleich! (Mandat des Himmels)

tobo
Beiträge: 1063
Registriert: 10.12.2008 10:51:41

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von tobo » 02.08.2021 12:18:29

Ne, stören tut es nicht. Ist halt nur stilistisch nicht so schön - man fordert was an und benutzt es dann nicht.

Benutzeravatar
detix
Beiträge: 1629
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: Mit Shellbefehl Key=Wert Paar auslesen?

Beitrag von detix » 02.08.2021 15:05:06

eval wäre auch noch eine Möglichkeit:

Code: Alles auswählen

eval $(</etc/os-release)
echo "$ID $VERSION_ID, $VERSION_CODENAME"
debian 11, bullseye
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Antworten