Einfache Datei mit Variablen erstellen und auslesen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,

    ich möchte Folgendes umsetzen: auf dem Pi soll eine Datei erstellt werden, die alle im Netzwerk relevanten Dateien enthält. Hierzu gehören verschiedene IPs, Benutzernamen, ggf. Passwörter (sofern sich diese ohne großen Aufwand verschlüsselt dort einfügen lassen) sowie unterschiedliche Dateipfade.

    Dies muss auch nicht unbedingt eine _einzelne_ Datei sein (z.B. zumindest die Pfade lassen sich definitiv in eine eigene Datei auslagern).

    Welches Format sollte die Datei haben? Pro Zeile ein Wert würde schnell unübersichtlich werden bzw. auch beim Auslesen unpraktisch sein, wenn mal ein Wert hinzugefügt wird und so versehentlich ein Wert in die nächste Zeile verschoben wird.


    Ich benutze zu 99% sehr simple bash Scripts auf meinem Pi (bin noch Anfänger), die fast alle mit verschiedenen IPs im Netzwerk arbeiten. Eben diese IPs würde ich gerne aus der Datei dort einfügen, statt sie von Hand einzugeben.

    "ssh user1@192.154.1.13" würde entsprechend zu "ssh 'var-datei:username1'@'var-datei:IP13'.

    Könnt Ihr weiterhelfen? Danke & LG

  • Einfache Datei mit Variablen erstellen und auslesen? Schau mal ob du hier fündig wirst!

  • > Welches Format sollte die Datei haben? Pro Zeile ein Wert würde schnell
    > unübersichtlich werden bzw. auch beim Auslesen unpraktisch sein, wenn
    > mal ein Wert hinzugefügt wird und so versehentlich ein Wert in die nächste
    > Zeile verschoben wird.
    Auf welcher Zeile die Variable steht, muss egal sein !

    Hier bietet sich der source-Befehl an:

    Das File variables:

    Code
    SSH_USER=user1@192.154.1.13
    .
    .
    .

    Und der Befehl zum Lesen des Files und setzen der Variablen:

    Code
    . variables

    Punkt - Whitespace - Filename

    Einmal editiert, zuletzt von Tell (27. März 2015 um 09:01)

  • Warum selber bauen ? Gibt es doch schon für SSH

    Code
    nano .ssh/config

    Inhalt :
    (Bei Key Auth kann der private Key mit angegeben werden)

    Danach auf der Console einfach :

    Code
    ssh pi13

    und alles ist gut ;)

    Offizieller Schmier und Schmutzfink des Forum.
    Warum einfach wenn's auch schwer geht ?

    Kein Support per PN !
    Fragen bitte hier im Forum stellen. So hat jeder etwas davon.

    Einmal editiert, zuletzt von Der_Imperator (27. März 2015 um 09:29)

  • Das Beispiel von Der_Imperator setzt voraus das für alle Zugänge ein SSH-Key eingerichtet wurde, allerdings müsste man eine passphrase für den SSH-Key dann trotzdem noch selber eingeben. Das wäre aber die sicherste Variante!

    Die von Tell genannte Variante würde ich persönlich etwas ausweiten und dazu dann halt noch ein Script verwenden um die jeweils gewollte Verbindung herzustellen...


    Mit den von dir gegebenen Infos kann man jetzt nur raten oder weitere Möglichkeiten (von den geschätzten 100) geben... Das wär aber etwas mühselig :D


    Handelt es sich denn nur um Verbindungen innerhalb deines LAN's ? Ist der Pi, auf dem diese gesammelten Daten gespeichert werden, nur innerhalb des LAN's zugänglich, also nicht von Extern / aus dem Internet? ... demnach würde sich imho richten inwiefern es wichtig wäre Sicherheit zu priorisieren.

    Was meinst du mit Pfaden? Was für Pfade sollen das sein? Für ein Zugang nur ein Pfad, oder mehrere?

    Wie wirst du das später nutzen? Also wofür soll das letztlich sein?

  • Danke für die Tipps.

    Mir geht es in diesem Fall aber nicht nur um das automatische Einloggen per SSH. War nur ein Beispiel. In manchen Scripts werden auch einfach IPs von im Netzwerk befindlichen Rechnern gepingt o.Ä.

    Ich habe heute gerade einen neuen Router installiert und kann jetzt jedes einzelne Script, das mit IP Adressen innerhalb meines Netzes arbeitet, neu konfigurieren. (note to self: DHCP abschalten ^^). Daher hätte ich gerne solche Dinge automatisiert in einer config-Datei. Es geht nicht nur um IPs, sondern z.B. auch das festlegen bestimmter Verzeichnisse etc.

  • Diese "Tag=value" Format ist schon eines, welches du verwenden solltest, wobei die Tags eineindeutig sein müssen.

    Wenn du Daten strukturiert ablegen willst/musst, empfielt sich das JSON oder XML Format.
    Diese Formate sind allerdings mit Kommandozeilenmitteln nicht mehr so einfach auslesbar - für Python gibt es fertige Module.

    Beispiel:

    Code
    #filename "daten"
    wetter=kalt
    ip=192.168.1.1
    mac=aa.bb.cc.dd.ee


    usw.

    So eine File kann einfach durchsucht werden:

    Code
    grep wetter daten

    mit dem befehl "cut" geht es weiter: der Trenner ist "=", du willst das 2. Feld, also:

    Code
    grep wetter daten | cut -d= -f2

    ... und schon hast du deinen Wert :bravo2:

    my2ct, das Zen

  • Hm naja und was ist wenn es mehrere Abschnitte mit 'wetter' gibt? :D Ganz so einfach ist das mit dem von dir genannten 'grep' aber auch nicht... Siehe Spoiler:

    Spoiler anzeigen
    Code
    root@raspberrypi:~# grep wetter daten /tmp/t
    grep: daten: Datei oder Verzeichnis nicht gefunden
    /tmp/t:wetter=kalt
    /tmp/t:wetter=kalt2
    /tmp/t:wetter=kalt3
    root@raspberrypi:~#

    Und für jeden Satz eine eigene Datei anlegen wär auch bissal komisch

    Also wenn denn würde ich dafür einen parser nehmen, eben wie für ini's. Mit dem kann man den jeweiligen Abschnitt ( [bla] ) wählen und dann das jeweilige Setting aus dem Abschnitt.

    Code
    [daten]
    wetter=kalt
    
    
    [daten2]
    wetter=kalt2

    Aber man könnte auch mit Arrays arbeiten

    Code
    Daten['wetter']=kalt
    Daten2['wetter']=kalt2

    Oder man arbeitet mit einer SQLite Datenbankdatei.

    Und das verschlüsselte speichern von Passwörtern könnte man mit der ' salt ' Methode bewerkstelligen...


    Also es gibt scho etliche Möglichkeiten - sind allerdings davon abhängig WAS man haben möchte oder welche Vielfalt an Daten man einbetten möchte. Ohne hierfür Beispiele zu sehen können Wir hier nur weiter Raten und alle Variationen abrattern auf der Hoffnung das evtl. eine zutreffend wäre.... *ächz*

  • meigrafd:

    Welchen Teil meines 1. Satzes (Hint: "eineindeutig") hast du nicht gelesen :lol:

    ne ne, is scho recht: Wenn es komplexer wird, wird es halt aufwendiger.

    Wir haben hier bei uns Konfigurationsfiles nach diesem Prinzip, die haben viele hundert Zeilen... werden allerdings maschinell erzeugt und auch wieder verarbeitet, da guckt auch eher selten einer rein...
    Wir steigen allerdings derzeit auf JSON um, das ist strukturiert und irgendwie praktischer :thumbs1:

    Nunja, ich denke, der TO muss sich entscheiden, welche Komplexität er sich zutraut...

    MfG, das Zen

  • z.B. möchte ich per ssh auf meinem Mac ein bestimmtes Script ausführen lassen. Dazu brauche ich folgende Variablen:

    #!/bin/bash
    ssh user@IP-Adresse
    ggf. Passworteingabe (ich habe dies mit lockkeys geregelt, alternativ die Lösung von Der_Imperator)
    osascript /pfad/zum/script / script.scpt

    Es wäre m.E. weitaus simpler, in einer Datei (für dieses Beispiel jetzt) folgende Informationen zu hinterlegen:

    User, IP-Adresse, ggf. Passwort, Pfad zum Script, Dateiname
    (natürlich könnte man Pfad & Dateiname zusammenfassen, da ich aber mehrere Scripte habe, wäre es so einfacher)

    Jedes Script, das auf diese -und andere- Informationen zugreift, soll einfach auf die Datei (json, xml, sql??) zugreifen, entsprechende Angaben abfragen und vor Ausführung des Scripts einfügen.
    Ändere ich nun mal die IP eines Gerätes oder den Pfad, in dem meine Scripts liegen, muss ich nicht mehr wie aktuell zig Scripts auf dem Pi bearbeiten, sondern _eine_ Datei, die diese Informationen an alle Scripts weitergibt.

    Ich muss erwähnen, dass ich noch blutiger Anfänger bin. Mit shell Scripts komme ich klar bzw. arbeite mich gerade so dort ein. Python und Co. stehen noch auf meiner Liste, das wird noch ein Weilchen dauern.

    Einmal editiert, zuletzt von raspberry314 (28. März 2015 um 09:06)

  • Naja gut, das ist aber nur ein Beispiel.. Ich kann das weiterhin schlecht einschätzen wie flexibel das ganze sein muss.. Auch frag ich mich halt 'was' auf diese Datenbank zugreift :s

    Du könntest das wie folgt probieren:

    - Eine Datei erstellen, zum Beispiel /usr/local/etc/daten.ini (Dateiendung spielt keine Rolle), mit folgendem Inhalt:

    (die SETTINGS sind absichtlich klein geschrieben, denn sonst werden Environment Variablen der aktuellen Session überschrieben (wie zB USER oder PATH))

    Dann erstellst du ein Script, zum Beispiel /usr/local/bin/DO mit folgendem Inhalt:

    die 3 echo's im Script sind nur fürs Debugging und zur Demonstration wie später eine bestimmte Variable abgerufen werden kann

    Script ausführbar machen: chmod +x /usr/local/bin/DO


    Wenn du jetzt DO eingibst wird dir folgendes ausgegeben:

    Du siehst also, für jedes SETTING wurde ein Array mit dem [SECTION] Namen erzeugt und dessen Variable zugewiesen. Diese Arrays kannst du dann in dem DO Script nach der while Schleife weiter verwenden (siehe echo Beispiel im DO script)

  • Du musst nicht 'DO' einzeln in jedes Script einfügen. Du kannst daraus eine function machen und brauchst diese dann nur auf bash Weise importieren sowie aufrufen.. Das erspart dir Code und erleichtert späteres ändern da du nicht 20x etwas ändern musst sondern nur ein mal. Generell sollte man bei sich wiederholenden Code Funtionen setzen.

    Beispiel:

    nano /usr/local/include/functions.sh

    (ein Shebang ist hier nicht nötig, ebenso wenig wie Ausführ Rechte!)

    Das funktioniert aber erst seit bash Version 4.2!
    Bei bash Versionen davor gibt es noch kein ' declare -g ' aber wenn man kein ' -g ' nutzt sind die Array's nur local in der Function. ' -g ' macht die Arrays also ' global '.

    Außerdem kann man den Aufruf dieser Funktion auch erweitern, mit Übergabe der gewünschten Section. Aber dann müsste man halt wissen welche Section's verfügbar wären, also wäre das nicht mehr ganz so flexibel.


    In deinem anderen Script machst du dann folgendes:

    Bash
    #!/bin/bash
    
    
    . /usr/local/include/functions.sh
    
    
    get_ini
    
    
    echo ${user[pi_2]}

    Das Leerzeichen zwischen Punkt und der Datei ist Absicht.
    Statt des Punkts kann man auch 'source' nutzen, also:

    Bash
    #!/bin/bash
    
    
    source /usr/local/include/functions.sh
    
    
    get_ini
    
    
    echo ${user[pi_2]}


    Ich versteh aber immer noch nicht wieso du zig verschiedene Scripts nutzen willst?

  • Das ist ja noch besser :)

    Naja, ich bin wie gesagt noch ein ziemlicher Anfänger. Für mich war es einfacher, für alle Möglichen Befehle, die ich brauche, einzelne Scripts zu erstellen. Vielleicht kann ich die irgendwann mal zusammenfassen, aber momentan fehlt mir dazu noch das Fachwissen.

  • Hier mal ein ganz simples Beispiel:

    an.sh

    Bash
    #!/bin/bash
    ssh user@mac
    osascript ~/pfad/an.scpt

    aus.sh

    Bash
    #!/bin/bash
    ssh user@mac
    osascript ~/pfad/aus.scpt

    Das ginge sicherlich auch viel einfacher, indem ich an_aus.sh erstelle und das mit an_aus.sh -an oder an_aus.sh -aus ausführe. Ich habe mich halt nur noch nicht damit befasst, wie das geht. Derzeit sind meine Script einfach alle sehr simpel, sodass das _noch_ nicht wirklich ins Gewicht fällt.

  • Naja du könntest das alles in einem Script zusammenfassen und dann mit entsprechenden Parametern aufrufen.

    Beispiel:

    nano /usr/local/etc/daten.ini

    nano /usr/local/include/functions.sh

    nano /usr/local/bin/DO && chmod +x /usr/local/bin/DO

  • Danke für den Tipp. Das ist mir gerade noch ein bisschen zu kompliziert.

    Ich würde das gerne so umsetzen:

    media.sh

    Ab hier weiß ich nicht weiter.
    Wie kann ich nun test.sh -datei1 bzw. test.sh -datei2 aufrufen?

    Ich habe ein Tutorial gefunden, was lediglich mit einstelligen Eingaben funktioniert; also media.sh -a oder media.sh -1 funktiniert; das konnte ich definieren und verwenden.

    Habe ich aber media.sh -on aufgerufen, hat das Script versucht, folgende Befehle zu starten
    media.sh -o
    media.sh -n

    Natürlich könnte ich die Funktionen auch alle einsilbig benennen. Der Übersicht halber wäre es aber schön, konkrete Befehle nutzen zu können. Beispiel:
    media.sh -on
    media.sh -off
    media.sh -mute
    media.sh -vol(x)

    Das funktioniert allerdings nicht. Wie gesagt, ich bin ein blutiger Anfänger und mir daher nicht mal sicher, was ich in diesem Fall googeln sollte. shell script Kommando? shell script Funktion?

    Wenn ich ein bisschen Zeit habe, möchte ich das alles mal ganz vom Anfang an aus lernen. Momentan muss ich aber erst einmal Shortcuts benutzen, um alles den Anforderungen gemäß umzusetzen ^^

    In diesem Script könnte ich praktisch sämtliche benötigten Variablen zum Anfang definieren und über die einzelnen (? Kommandos? Funktionen?) den jeweiligen Anforderungen zuweisen, anstatt zig einzelne .sh-Dateien erstellen zu müssen.

  • Was ist dir daran zu kompliziert? Hab dir das doch fix und fertig vorgekaut :s


    Google mal nach: /bin/bash parameter
    Oder: /bin/bash case
    Oder: /bin/bash multiple options

    Wissen sollte man halt das jeder übergebene Parameter durch ein Leerzeichen getrennt unterschieden wird. So wäre zB bei:

    Code
    ./media.sh -o off

    " -o " das erste Parameter und über bash in $1 hinterlegt, " off " das zweite Parameter und in $2 hinterlegt usw.

    Nun wärs halt davon abhängig was genau du erreichen möchtest usw. Anhand dessen was du gepostet hast kann ich leider nicht wirklich nachvollziehen wie das funktionieren soll, das kommt wenn dann wieder auf dutzende einzelne Scripts raus was ich persönlich als Quatsch empfinde.

  • Danke! Ich habe es mit diesem Beispiel gelöst:
    http://www.willemer.de/informatik/unix/shskript.htm

    test

    Code
    case "$1" in
         haus) echo "house" ;;
         auto)  echo "car" ;;
         kind)  echo "child" ;;
         *) echo "stuff" ;;
    esac

    ./test haus
    -->
    house

    Als 'control' kann ich in dieser Datei dann erst einmal alle Variablen eintragen... IPs, Usernamen, Pfade, ggf. verschlüsselte PWs, was sonst noch so anfällt...

    ./control mediaon loggt sich nun per ssh auf dem Medienserver ein, started das Programm, deaktiviert automatischen Ruhezustand etc.

    ./control mediaoff beendet endsprechend das Programm und setzt die Energiesparoptionen zurück etc.

    Ich verstehe so ganz, warum ich hier mit zwei Variablen arbeiten soll. Ob ich nun
    ./control -media on
    oder
    ./control mediaon
    starte, macht doch an sich keinen Unterschied... Oder?

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!