Der Code-Schnippsel-Thread

  • So gehts:

    Bash
    #!/bin/bash
    arr=(Foo1 Foo2 Foo3)
    echo ${arr[0]}

    Ausgabe:

    Code
    11:28 merlinfeld@borsenmac /Users/merlinfeld
    % bash arr.sh
    Foo1

    Gewöhn dir am besten bei allen Variablen in Bash an, ihre Namen in {} einzupferchen, zum Beispiel ${example}


  • So gehts:

    Bash
    #!/bin/bash
    arr=(Foo1 Foo2 Foo3)
    echo ${arr[0]}

    Gewöhn dir am besten bei allen Variablen in Bash an, ihre Namen in {} einzupferchen, zum Beispiel ${example}

    In so 'ne Falle bin ich selber auch mal reingetappt. Scheiße, wenn man Powershell sowie C# oder gar die fish-Shell gewohnt ist.

    Make the WHF great again!

    Einmal editiert, zuletzt von Blue (8. Juni 2021 um 06:27)


  • Gewöhn dir am besten bei allen Variablen in Bash an, ihre Namen in {} einzupferchen, zum Beispiel ${example}

    Bei der Gelegenheit sollte man sich auch gleich angewöhnen, immer "${foo}" zu schreiben, vor allem, wenn man es mit Datei-/Directorynamen zu tun hat, die Leerzeichen beinhalten können, insb. bei so Sachen wie for f in *; do … (also Files in einer Schleife behandeln) usw. Oder gibt es dafür einen besseren Weg, den ich noch nicht entdeckt habe?

    Wüsste jetzt auch aus dem Steigreif nicht, wie sich das {} in find . -type f -iname "*.bla" -exec command {} \; verhält.

    Und ja, da ist noch find -print0 nach xargs -0 pipen.

    • • • – • – – • – –

    Einmal editiert, zuletzt von s4ndwichMakeR (8. Juni 2021 um 18:50)

  • Ebenso sollte man bei Bash-Scripten immer beachten, dass Schleifen mit dem Keyword 'do' eröffnet und mit 'done' abgeschlossen werden. Jedes mal vergess ich das nämlich, weil von anderen C-like-Sprachen gewohnt, die geschweiften Klammern den Beginn und das Ende des jeweiligen Blocks definieren. Nur haben die bei der Bash halt ne andere Funktion als den Beginn und Abschluss eines Anweisungsblocks zu kennzeichnen.

    Make the WHF great again!


  • Ebenso sollte man bei Bash-Scripten immer beachten, dass Schleifen mit dem Keyword 'do' eröffnet und mit 'done' abgeschlossen werden. Jedes mal vergess ich das nämlich, weil von anderen C-like-Sprachen gewohnt, die geschweiften Klammern den Beginn und das Ende des jeweiligen Blocks definieren. Nur haben die bei der Bash halt ne andere Funktion als den Beginn und Abschluss eines Anweisungsblocks zu kennzeichnen.

    Das ist kein spezifisches Bash-Feature, sondern schon von der Bourne Shell geerbt. Stephen Bourne hatte nicht etwa C als Inspiration für die Strukturen, sondern ALGOL, wo eben mit Keywords statt mit Klammern gearbeitet wird. Auf den Maschinen der Zeit – da war ja selbst ASCII noch relativ neu – konnte man sich nicht darauf verlassen, dass man überhaupt eine große Auswahl an Klammern im Zeichensatz zur Verfügung hatte. Offenbar konnte man sich lediglich auf ( und ) verlassen, denn immerhin definiert ALGOL sogar Keywords für < und > als Vergleichsoperatoren (lt bzw. gt). Frühe Programmiersprachen waren stark naturalistisch mit echten Wörtern statt Zeichen, weil [A-Z] und rudimentäre Interpunktion und mathematische Symbole der kleinste gemeinsame Nenner der Zeichensätze war – außer vielleicht beim APL-Zeichensatz, der als Gegenteil hier deutlich hervorsticht. C setzte dann schon implizit auf ASCII-unterstützende Maschinen, auch wenn in The C Programming Language afair noch EBCDIC an einigen Stellen erwähnt wird (müsste bei mathematischen Operation auf char-Variablen wie z.B. für Case-Umwandlung der Fall sein).

    • • • – • – – • – –

  • Backup-Script

    Ausgabe

    Irgendjemand ne Idee, was hier falsch läuft? Wenn ich die function tier3_Backup definiere und dann ausführe, dann tut alles.


    Meine Beiträge stehen unter der MIT-Lizenz:D


    externe HDD am Router? Klar ich tausch mein Auto gegen nen Tretroller mit Bremsklotz.

    Einmal editiert, zuletzt von tk1908 (19. August 2021 um 12:11)

  • Folgender Code gibt bei Windows 10 und Windows 11 exakt das selbe aus:

  • Ein Beispiel für den Umgang für read mit einer Pipeline:

    Standardmäßig führt Bash jedes Element einer Pipeline in seiner eigenen Subshell aus, was beim Idiom

    Code
    Befehl | while read var1 var2 var3; do ...; done


    nicht weiter auffällt und sogar oft wünschenswert ist, dass der äußere Geltungsbereich nicht mit $var1, $var2, $var3 verschmutzt wird.
    Mit der Shell-Option lastpipe kann man seit Bash 4.2 in einem Shell-Skript (oder einer interaktiven Shell mit deaktiviertem Job Control) das letzte Element einer Pipeline ohne Subshell ausführen, sodass zum Beispiel wie hier Variablen nicht-flüchtig gesetzt werden können. Dieses Verhalten ist ansonsten nur in der originalen Korn-Shell (ksh93) zu finden, aber genauso wenig in pdksh/mksh.
    ZSH und ältere Bash-Versionen müssen auf Prozessersetzung zurückgreifen, in anderen Shells geht dies nur mit einer temporären Datei:

    Code
    read -r jenv jverstr jversion < <("$JAVA" -version 2>&1 | head -n 1)
  • Ich werf hier mal wider was rein:

    Problem ist, dass das for-Command (bspw. im 1080p-Block) fehlschlägt, sobald keine Files im entsprechenden Ordner liegen. Irgendeine Idee, wie ich hier vorgehen kann? (Möglichst ohne großartiges if else gefriemel?)


    Meine Beiträge stehen unter der MIT-Lizenz:D


    externe HDD am Router? Klar ich tausch mein Auto gegen nen Tretroller mit Bremsklotz.


  • Problem ist, dass das for-Command (bspw. im 1080p-Block) fehlschlägt, sobald keine Files im entsprechenden Ordner liegen. Irgendeine Idee, wie ich hier vorgehen kann? (Möglichst ohne großartiges if else gefriemel?)

    Klingt, als könne der Wildcard-Ausdruck nicht expandiert (aufgelöst) werden und wird folglich wörtlich übergeben. Entweder benutzt du auch dort find, das prinzipiell nur existierende Dateien findet (anders als for, das nur über eine von der Shell übergebene Liste iteriert) oder prüfst auf Existenz mit [ -e "$f" ] && ffmpeg ….

    Mag sein, dass es eine elegantere Lösung gibt (irgendeine via set setzbare Shell Option?), weil das ja eine verbreitete Stolperfalle sein dürfte. Ich stand aber bisher nicht vor dem Problem.

    • • • – • – – • – –


  • Mag sein, dass es eine elegantere Lösung gibt (irgendeine via set setzbare Shell Option?), weil das ja eine verbreitete Stolperfalle sein dürfte. Ich stand aber bisher nicht vor dem Problem.

    Ja, für Bash gibt es nullglob:

    Zitat

    nullglob: If set, bash allows patterns which match no files (see Pathname Expansion) to expand to a null string, rather than themselves.

    Code
    /var/empty$ for x in *.mp4; do echo "verarbeite $x"; done
    verarbeite *.mp4
    /var/empty$ shopt -s nullglob
    /var/empty$ for x in *.mp4; do echo "verarbeite $x"; done


    Das funktioniert, weil for ohne in (bzw. in ohne Argumente) gültige Syntax ist.
    In diesem Fall sollte es nicht schaden, die Option für das ganze Skript zu setzen.

  • Einfacher Wrapper für den Git-Credentialhelper store, der Zugangsdaten symmetrisch mithilfe OpenSSL verschlüsselt (Hausaufgabe: durch öffentlichen Schlüssel mithilfe GnuPG), soweit kein geeigneter plattformspezifischer Speicher (Windows-Anmeldeinformationsverwaltung, macOS-Schlüsselbund, KWallet/gnome-keyring) zur Verfügung steht:


    Einrichtung:

    Code
    git config [--global] credential.helper /pfad/zur/store-crypt

Jetzt mitmachen!

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