Bash: Wie eval ersetzen/loswerden?

  • Bevor ich auch noch meine verbliebenen Haare ausraufe, stelle ich hier mal eine Frage zur bash-Programmierung.

    Im Projekt "Dokumentation für raspiBackup" habe ich Tools gebaut, die den Autoren etwas unter die Arme greifen sollen.

    Bei einem der Tools nutze ich leider noch eval, welches ich gerne loswerden möchte.
    Nach vielen vergeblichen Versuchen, die bash zur Mitarbeit zu überreden, habe ich hier ein Minimalbeispiel gebaut:

    Das Script soll gesourced werden, so dass die Aliase (und im Original weitere Dinge) in der aktuellen Shell aktiv sind/werden.

    Also:

    Bash
    source mwe

    Damit werden dann die beiden Aliase xbs und ybs aktiv.

    Das Problem tritt auf bei ybs, weil dort bei EDIT_IN_TABS="vim -p" ein Leerzeichen enthalten ist.
    Dieses wird beim Verzicht auf eval nicht wunschgemäß verarbeitet und führt zum Fehler bash: vim -p: Befehl nicht gefunden..., weil nicht vim -p, sondern 'vim -p' aufgerufen wird.

    Wie geht es richtig? Ich sehe den Wald vor lauter Bäumen nicht mehr.

    Vermutlich ist das für Bash-Gurus einfach zu lösen, deshalb frage ich ja hier. ;)

  • funktionieren nicht:

    # "${EDIT_IN_TABS}" file1 file2 # + 'vim -p' file1 file2 ==> bash: vim -p: Befehl nicht gefunden...

    # ${EDIT_IN_TABS} file1 file2 # + 'vim -p' file1 file2 ==> bash: vim -p: Befehl nicht gefunden...

    Bei mir funktioniert #2 und so würde ich auch das eval entfernen :denker:

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Wenn dann Dir raspiBackup den Ar*** gerettet hat

    solltest Du fairerweise diese Seite besuchen und ein Trinkgeld spendieren :shy:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

  • Bash
    framp@majestix:~/test$ bash --version
    GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)

    Daran liegt es aber nicht und ich konnte es mir auch nicht vorstellen denn das ist wie gesagt der Weg wie man ohne eval auskommt.

    Und eben hatte ich wohl einen Geistesblitz und habe rausgefunden woran es liegt :bravo2:

    Ich habe die Angewohnheit bash Scripten immer die Extension .sh anzuhängen. D.h. bei mir heisst die Datei nicht mwe sondern mwe.sh Nachdem ich sie in mve umbenannt habe funktioniert #2 bei mir auch nicht :wink1:

    Frage mich jetzt aber nicht warum es nur mit Extension funktioniert.

    EDIT: Falsche Aussage durchgestrichen

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Wenn dann Dir raspiBackup den Ar*** gerettet hat

    solltest Du fairerweise diese Seite besuchen und ein Trinkgeld spendieren :shy:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

    Edited once, last by framp (June 27, 2025 at 4:43 PM).

  • Mit der Extension hat das nichts zu tun. Dein Hinweis hat mir geholfen. Wenn man das Fenster neu aufmacht funtkioniert es sowohl mit als auch ohne .sh.

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Wenn dann Dir raspiBackup den Ar*** gerettet hat

    solltest Du fairerweise diese Seite besuchen und ein Trinkgeld spendieren :shy:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

  • Ich habe jetzt versucht das noch mal zu reproduzieren dass es bei mir bei #2 failed und dabei habe ich festgestellt dass #2 auskommentiert war und #1 aktiv. Da bin ich wohl irgendwo verrutscht beim unkommentieren. jedenfalls kann ich es nicht mehr reproduzieren dass #2 nicht funktioniert.

    Ab und zu mal eine neue Shell öffnen, damit es klappt, kann es ja nicht sein.

    Du hast ja ein MWE von Deinem existierenden Code erstellt. Funktioniert das MWE jetzt mit dem neuen Fenster und/oder auch der existierende Code?

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Wenn dann Dir raspiBackup den Ar*** gerettet hat

    solltest Du fairerweise diese Seite besuchen und ein Trinkgeld spendieren :shy:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

  • Vermutlich habe ich die Ursache gefunden.

    Das Original-Script ohne eval klappte auch nicht in einem neuen Fenster.
    Das Mini-Script mwe klappte nicht, wenn es in der selben Shell-Session aufgerufen wurde, in der zuvor das Original-Script lief. Genauer: Eine Funktion davon. Aha! :!:

    Im Original-Script wird die Variable IFS temporär verändert. Auf eine Art, bei der ich dachte, dass das nur für das aktuelle Kommando gilt

    Bash
     IFS=$'\n' command ...

    Falsch gedacht. Die IFS bleibt dann so und beeinflusst natürlich nachfolgende Kommandos.

    Ich habe IFS jetzt an passender Stelle wieder auf den ursprünglichen Wert restored. Und jetzt klappt es auch ohne eval.

    Edited once, last by simonz (June 27, 2025 at 6:28 PM).

  • aber wieso ist das überhaupt nötig

    Die führst nach dem Umsetzen des IFS keinen Befehl aus sondern ein bash Statement. D.h. Die Zeile

    Bash
    IFS=$'\n' FILES=($(rg --files-without-match "^\[\.status\]:" --glob="**/*.md" | sort | fzf --reverse --exact --multi --bind alt-a:select-all,alt-d:deselect-all --preview='cat {}' --header=">> Please select file(s) to edit and press ENTER. (ESC to cancel.) <<"))

    ist nichts anderes als

    Bash
    IFS=$'\n' 
    FILES=($(rg --files-without-match "^\[\.status\]:" --glob="**/*.md" | sort | fzf --reverse --exact --multi --bind alt-a:select-all,alt-d:deselect-all --preview='cat {}' --header=">> Please select file(s) to edit and press ENTER. (ESC to cancel.) <<"))

    und damit wird IFS nicht temporär umgesetzt. Du nutzt ja shellcheck. Kam da nicht SC2207 ?

    IFS=$'\n' command ...

    Falsch gedacht. Die IFS bleibt dann so und beeinflusst natürlich nachfolgende Kommandos.

    Jein. Nicht falsch gedacht. Aber es muss ein Command sein damit die IFS Änderung temporät ist und kein Bash Statement was die Zuweisung ja ist.

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Wenn dann Dir raspiBackup den Ar*** gerettet hat

    solltest Du fairerweise diese Seite besuchen und ein Trinkgeld spendieren :shy:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

  • Hier ein kurzes Testscript für das Verhalten:

    Das Thema ist damit nun erledigt. Vielen Dank für's Mitmachen!

  • simonz Besser wäre wohl:

    Code
    echo "$LANG"
    # de.DE.UTF-8
    myLANG="$LANG"
    
    ...
    
    LANG="$myLANG"

    Da braucht man sich keine Gedanken machen, was vorher in $LANG stand. Das senkt marginal den Fehlerteufel.

  • Das hat simonz dann ja auch gemacht. Er wollte verstehen warum es nicht funktioniert und hat nach meiner Erläuterung ein kleines Demoscript geschrieben mit dem es deutlich wird.

    :no_sad: ... Kein raspiBackup - kein Mitleid ... :no_sad:

    Wenn dann Dir raspiBackup den Ar*** gerettet hat

    solltest Du fairerweise diese Seite besuchen und ein Trinkgeld spendieren :shy:

    Mein Raspberry Zoo

    3 * RPi1B, 2 * RPi3B, 2 * RPI4, 1 * CM4, 1 * RPi5

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!