Bash Kommando an Variabel übergeben und anzeigen

  • Hallo,
    ich bin neu in der Skrip-Programmierung in Linux(Raspbian). Ich möchte die Ausgabe eines Kommandos (cangen) in eine Variabel speichern und spätter in meinem Skript verarbeiten.

    Mit dem Befehl "cangen" generiere ich anhand eines virtuellen CAN-Bus-Interface CAN-Bus Daten. Diese Daten möchte ich immer in einer Variabel speichern. Normalerweise bekomme ich solche Daten, wenn ich den Befehl ausführe(Anhang):

    Befehl:

    Code
    cangen vcan0 -g 4 -I 7E -L 8 -D r -v


    Ausgabe: http://www.bilder-upload.eu/show.php?file=…-1470922561.jpg
    show.php?file=0263db-1470922561.jpg


    Nun möchte folgender Skript, die Ausgabe des Befehls in einer Variabel speichern:


    Leider bekomme ich keine Ausgabe. ich bekomme nur die Nachricht:

    Code
    RTNETLINK answers: File exists


    Ich habe nicht sehr viel Erfahrung in Python und die Programmierung mit Skript in Linux, deswegen wollte ich mal hier fragen, ob jemand mir helfen könnte meine Herausforderung zu lösen.

    Ich benutze das Raspberry Pi 3

    Danke

  • Das ganze "sudo" ist in dem Script nicht nötig wenn das Script selbst via sudo ausgeführt wird.

    Bei bash ist wichtig das kein Leerzeichen zwischen bla und = steht ... Bei dir sehe ich aber eines :fies:
    Falsch:

    Code
    candata= `cangen vcan0 -g 0.008 -I 7E -L 8 -D r -v`


    Richtig:

    Code
    candata=`cangen vcan0 -g 0.008 -I 7E -L 8 -D r -v`

    Ich persönlich bevorzuge:

    Code
    candata=$(cangen vcan0 -g 0.008 -I 7E -L 8 -D r -v)
  • danke für deine Antwort :thumbs1: .

    Ich weiß mittlerweile, dass der Befehl:


    Code
    sudo ip link add dev vcan0 type vcan

    nur einmal ausgeführt werden muss. Denn das CAN-Interface nur einmal erzeugt werden kann. Dann kann man die CAN-Daten generieren. Ich musste den Raspberry Pi neustarten, damit ich den Script ohne Meldung ausführen konnte. Die Ausgabe wird trotzdem nicht angezeigt. Ich vermute, dass die Daten in der Variabel gespeichert sind aber die Konsole schaft es nicht, die Daten zu zeigen. Vielleicht benutze ich nicht richtige Methode um die Daten anzuzeigen :wallbash: .

    Eigentlich möchte ich aus den erzeugten Daten nur die Hex Zahlen verwenden:
    Zum Beispiel:
    Ausgabe des Befehls:

    Code
    vcan0  07E#65.45.7B.78.89.67.89.6A


    Ich brauche nur:

    Code
    0 7E 65 45 7B 78 89 67 89 6A

    Aber davor wollte ich zuerst die Daten anzeigen lassen das gelingt mir noch nicht...

  • adora: Wo ist da der Unterschied zu dem aus Beitrag#3?


    Dafür hast du mehrere Möglichkeiten - wie immer :fies:

    Das folgende nennt sich 'pipe' ... Die Ausgabe des vorherigen Befehls wird an den Nachfolgenden übergeben:

    Code
    candata="vcan0  07E#65.45.7B.78.89.67.89.6A"
    
    
    echo $candata | cut -d" " -f2
    #oder:
    echo $candata | awk {'print $2'}

    Und wenn du die Punkte noch weg haben willst eine Pipe an:

    Code
    tr '.' ' '

    awk könnte das auch - ist allgemein sehr mächtig der Befehl...

    Oder mit sed:

    Code
    sed 's/\./ /g'

    Aber selbst bash kann das:

    Code
    candata=$(echo $candata | awk {'print $2'})
    echo ${candata//./ }

  • adora: Wo ist da der Unterschied zu dem aus Beitrag#3?


    meins ist besser zu lesen
    *edit:ist natuerlich kein unterschied, ich hab mal wieder was uebersehen.


    Leider bekomme ich keine Ausgabe. ich bekomme nur die Nachricht:

    Code
    RTNETLINK answers: File exists

    es wird daran liegen das mehrere lines zurueck kommen.
    versuch:

    Code
    candata=$( (echo $candata | awk {'print $2'}) )
    echo "${candata[@]}
    oder
    candata="$(echo $candata | awk {'print $2'})"
    echo "${candata}

    Einmal editiert, zuletzt von adora (11. August 2016 um 19:08)

  • :thumbs1: Danke für Ihre Hilfe!! :thumbs1:

    Ich weiß nun wieso die Daten nicht angezeigt worden sind.
    Das Programm blieb immer bei der Zuweisung in die Variabel hängen:
    Der Befehl:

    Code
    cangen vcan0 -g 0.008 -I 7E -L 8 -D r  -v


    erzeugt eine unendliche Schleife, in der Daten erzeugt werden. Die Zuweisung:

    Code
    candata=$(cangen vcan0 -g 0.008 -I 7E -L 8 -D r -v)


    ist also unendlich weiter, so dass die folgenden Befehle nicht ausgeführt worden sind :wallbash: .
    Erst nachdem ich nochmal die Eigenschaften des "cangen"-Befehl habe ich herausbekommen, dass man einen weiteren Parameter "-n" hinzufügen muss, um die Anzahl der zu erzeugten Daten zu bestimmen. Nachdem ich den Parameter hinzugefügt habe, kann ich nun die Daten anzeigen lassen :thumbs1: . Mein Programm sieht nun wie folgt aus:

    Mit einer unendlichen While-Schleife kann ich immer eine Ausgabe/Zyklus anzeigen lassen.

    Ich hätte eine Frage über das selektieren und das Speichen in einem Array. Momentan sehen meine Daten so aus:

    Code
    vcan0  07E#65.45.7B.78.89.6A

    Ich möchte in einem Array z.B. a=[15] alle Hexa-Daten speichern.
    Ziel ist es diese Array in meinem C-Programm weiterzuleiten. Denn ich programmiere in C und brauche als Eingang diese erzeugte Daten. Da ich aber nicht so gut bei der Python Programmierung bin, ist es richtig schwierig für mich manche Zusammenhänge zu verstehen.

    Ich freue mich auf jede Idee...

    P.S. @meigrafd ich habe schon das "Pipe" mit deinen Vorschlägen ausprobiert und es hat auch funktioniert. Danke

  • Wenn dein C Programm bereits läuft wird eine Übergabe schwieriger - da bliebe nur eine FIFO Datei oder zB Socket. Ansonsten halt eine Parameterübergabe - aber ein ganzes Array? :denker:

    Wenn du in C programmierst kannst du doch eigentlich besser die nötigen Sachen aus https://github.com/linux-can/can-utils/blob/master/cangen.c raus lutschen und direkt in dein C Programm integrieren oder nicht? :s
    (wobei ich nicht weiß ob der Source der richtige ist)


  • Da ich aber nicht so gut bei der Python Programmierung bin, ist es richtig schwierig für mich manche Zusammenhänge zu verstehen.

    du weisst schon das das hier bash-programmierung ist und nicht python?



    Ich möchte in einem Array z.B. a=[15] alle Hexa-Daten speichern.
    Ziel ist es diese Array in meinem C-Programm weiterzuleiten. Denn ich programmiere in C und brauche als Eingang diese erzeugte Daten.

    Einmal editiert, zuletzt von adora (12. August 2016 um 18:41)

  • So wie es adora gezeigt hat funktioniert es leider nicht - mal davon abgesehen das es "do" und nicht "di", und $ziele heißt... Das Problem ist die letzte for Schleife. Es handelt sich um ein Array nicht um eine normale Variable, dh es muss auch entsprechend behandelt werden.


    Um die Array-Indexes auszugeben muss man es quasi so schreiben:

    Code
    echo ${!a[@]}

    Möchte man nur alle Werte und ignoriert das jeweilige Index:

    Code
    echo ${a[@]}

    Möchte man alle indexes abarbeiten müsste es so aussehen:

    Code
    for x in ${!a[@]}; do
        param+=" ${a[$x]}"
    done

    Allerdings ist das auch unschön da dann direkt ein "Leerzeichen" am Anfang von $param stehen würde

    Aber ich empfehle in diesem Fall vorheriges (Einzeiler), das sparrt ne menge Code ;)


    In bash sollte man ein array vorher als solches deklarieren um die Eigenschaften der Variable festzulegen:

    Code
    declare -a bla

    Wichtig: sh ist älter als bash und kann das noch nicht, aber auch bash kann das erst seit v4

    Eine Alternative zu dem offensichtlichen Variable[Index]=Wert Verfahren wäre sowas:

    die for Schleife ist natürlich nur um den Wert eines bestimmten Index's auszugeben... In diesem Fall das index "burb"
    BTW: Es handelt sich dabei quasi nur um eine Liste mit Trennzeichen.

    Damit arbeite ich eigentlich recht gerne da es dann keine Rolle spielt welche bash Version vorhanden ist. Aber sh kann damit nicht umgehen. Man sollte heutzutage aber sowieso primär bash nutzen, es sei denn man weiß wirklich wieso nicht...

    Besseres Beispiel:
    [code=php]
    declare -a bla
    for i in {1..5}; do
    bla[i]="wert$i"
    done

    param=${bla[@]}
    echo $param

    # cprog "$param"
    [/php]

    Den Unterschied zwischen param+=" wert" sieht man btw nur wenn man echo "$param" verwendet - ein Fix für dieses unschöne Leerzeichen ganz am Anfang wäre:
    [code=php]
    declare -a bla
    for i in {1..5}; do
    bla[i]="wert$i"
    done

    for x in ${!bla[@]}; do
    [ -z "$param" ] && param=${bla[$x]} || param+=" ${bla[$x]}"
    done

    echo "$param"
    [/php]

    Und last but not least... Das funktioniert auch:
    [code=php]
    declare -a bla
    for i in {1..5}; do
    bla[i]="wert$i"
    done

    for x in ${!bla[@]}; do
    [ -z "$param" ] && param=${bla[x]} || param+=" ${bla[x]}"
    done

    echo "$param"
    [/php]wer sieht den unterschied? ;)


    Siehe dazu auch: http://www.linuxjournal.com/content/bash-arrays


    Und eine allgemeine Empfehlung: https://wiki.ubuntuusers.de/Shell/Bash-Skr…_Anf%C3%A4nger/

  • stimmt, da waren 2 fehler, ziele statt zeile und $a anstatt ${a[@]}
    das di und do hatte ich schon selber nach 1 min berichtigt.

  • Naja siehe Beitrag#11, da steht doch schon alles.

    Wozu

    Code
    for zeile in ${a[@]} ; do
      param+=" $zeile"
    done


    wenn auch

    Code
    param=${a[@]}

    reicht? :s
    Zumal dein Weg ein unnötiges Leerzeichen am Anfang hinzufügt..


  • Naja siehe Beitrag#11, da steht doch schon alles.

    Wozu

    Code
    for zeile in ${a[@]} ; do
     param+=" $zeile"
    done


    wenn auch

    Code
    param=${a[@]}

    reicht? :s
    Zumal dein Weg ein unnötiges Leerzeichen am Anfang hinzufügt..

    ja, sehr schoener beitrag #11, aber #12 sollte eigentlich auch nur die fehlerkorrektur von #10 sein.
    zu deiner frage, deins reicht, meins reicht, bin halt gewohnheits mensch und mach es so wie immer, und mich stoert nicht mal das space. ;)
    bevor ich das mit param=${a[@]} mache wuerd ich es erstmal testen, ganzes array hab ich auch noch nicht uebergeben,
    zumindest nicht ausserhalb bash

    Einmal editiert, zuletzt von adora (13. August 2016 um 15:03)

  • hatte #11 nicht gross gelesen weils einer deiner ueblich klugscheisser beitraege war.

    Bitte was?

    Wenn jemand etwas falsches postet und dies dann korregiert wird, ist derjenige automatisch ein klugscheißer? :-/

    Entschuldige wenn Ich es sinnvoller finde jemandem auch den Code zu erklären und verschiedene Möglichkeiten bzw Unterschiede aufzuzeigen.... Einfach nur irgendeinen Code, auch noch falscher, vor die Füße klatschen findest Du also besser?

    Vielleicht solltest Du dir mal angewöhnen nicht nur die anderen Beiträge in einem Thread, sondern auch deine Eignen genauer zu betrachten

  • Du hattest Dein(e) Fehler zu dem Zeitpunkt nicht korrigiert. Siehe Beitrag#10

    du weisst schon das das hier bash-programmierung ist und nicht python?



    Und dann fragst Du auch noch wieso ich "mal davon abgesehen das es "do" und nicht "di", und $ziele heißt" schreibe


    wollte nur den fehler berichtigen, hatte auch nicht verstanden warum du schriebst "und $ziele heißt..", ein $ gehoert da nicht.
    hatte #11 nicht gross gelesen weils einer deiner ueblich klugscheisser beitraege war.

    genauer hingucken dann siehst du es vielleicht!

    ich glaub Du bist nicht Kritikfähig... Deshalb fasst du meinen umfassenden Beitrag#11 auch als Beleidigung oder Klugscheißer-Beitrag auf.


    ... im out ...

Jetzt mitmachen!

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