24 Punkte von GN⁺ 2025-10-23 | 2 Kommentare | Auf WhatsApp teilen
  • Stellt die meistgenutzten shell-Skripte aus einer Sammlung verschiedener Skripte vor, die beim Pflegen von dotfiles über mehr als 10 Jahre entstanden sind
  • Unterteilt in Zwischenablage, Dateiverwaltung, Internet, Textverarbeitung, REPL-Starter, Datum/Uhrzeit, AV, Prozesse, Schnellreferenz, System, Sonstiges; jedes Skript wird als kurzer Wrapper mit praxisnahen Beispielen gezeigt
  • Die meisten Skripte funktionieren unter macOS und Linux; die Kernidee ist, „die lästigen Kleinigkeiten vorhandener Werkzeuge zu glätten
    • Integration gängiger Utilities wie pbcopy/xclip, python3 -m http.server, yt-dlp, ffmpeg, mpv usw.
  • Zu den am häufigsten verwendeten gehören copy/pasta/pastas/cpwd, mkcd/tempe/trash/mksh, serveit/getsong/getpod/getsubs, scratch/straightquote/markdownquote, timer/boop/tunes usw.

Vorstellung der meistgenutzten Skripte aus meinen gepflegten dotfiles

  • Aus den verschiedenen shell-Skripten, die beim Verwalten persönlicher dotfiles über mehr als 10 Jahre entstanden sind, werden die am häufigsten genutzten nach Bereichen geordnet vorgestellt
  • Jedes Skript wird zusammen mit Zweck, Nutzungshäufigkeit und repräsentativen Beispielen beschrieben, um die sofortige Einsetzbarkeit zu erhöhen
  • Gemeinsame Ziele sind die Verkürzung wiederkehrender Arbeiten, Abstraktion über Plattformen hinweg sowie mehr Sicherheit und bessere Lesbarkeit

Skripte rund um die Zwischenablage

  • copy und pasta: Wrapper um den System-Zwischenablage-Manager, basierend auf pbcopy unter macOS oder xclip unter Linux
    • copy: kopiert die Ausgabe in die Zwischenablage
    • pasta: holt Text aus der Zwischenablage und gibt ihn aus
    • Beispiele: run_some_command | copy, pasta > file.txt, vim "$(pasta)", pasta | base64 --decode
  • pastas: ein Tool, das bei jeder Änderung der Zwischenablage den neuen Inhalt in Echtzeit ausgibt
    • Nützlich, um alle kopierten Links in einer Datei zu speichern oder mehrere Links gesammelt herunterzuladen
    • Beispiele: pastas > everything_i_copied.txt, pastas | wget -i -
  • cpwd: kopiert den Pfad des aktuellen Verzeichnisses in die Zwischenablage
    • Praktisch beim Wechseln von Verzeichnissen über mehrere Terminal-Tabs hinweg

Skripte zur Dateiverwaltung

  • mkcd foo: erstellt ein Verzeichnis und wechselt sofort hinein (Kurzform für mkdir foo && cd foo)
  • tempe: wechselt in ein temporäres Verzeichnis (cd "$(mktemp -d)"); bei temporären Arbeiten in einer Sandbox-Umgebung ist kein Aufräumen nötig
    • Beispiel:
      # Download a file and extract it  
      tempe  
      wget 'https://example.com/big_file.tar.xz'  
      tar -xf big_file.tar.xz  
      # ...do something with the file...  
      
      # Write a quick throwaway script to try something out  
      tempe  
      vim foo.py  
      python3 foo.py  
      
  • trash: verschiebt Dateien in den Papierkorb (unterstützt macOS/Linux), um Fehler im Vergleich zu einfachem rm zu vermeiden
  • mksh: erstellt eine neue Shell-Skriptdatei, macht sie ausführbar und öffnet sie sofort im Editor

Skripte rund ums Internet

  • serveit: startet einen statischen Dateiserver aus einem lokalen Verzeichnis (standardmäßig Port 8000, mit Alternative falls Python nicht installiert ist)
  • getsong lädt mit yt-dlp Audiodateien in der besten verfügbaren Qualität herunter
  • getpod ist ein Wrapper, der Videos als podcasttaugliches Audio herunterlädt
  • getsubs extrahiert englische Untertitel mit einer Logik aus bevorzugt offiziellen Untertiteln und Fallback auf automatische Untertitel. Geeignet für Zusammenfassungs-Pipelines und als Backup
  • wifi off/on/toggle: steuert das System-WLAN, nützlich bei der Fehlersuche im Netzwerk
  • url: parst URL-Strings und trennt bzw. extrahiert Protokoll, Hostname, Pfad, Query, Hash usw.

Skripte zur Textverarbeitung

  • line 10: gibt eine bestimmte Zeile aus der Standardeingabe aus (ähnlich wie head oder tail)
  • scratch: dient dazu, mit $EDITOR $(mktemp) schnell einen temporären Textpuffer in Vim zu öffnen; geeignet für einmalige Notizen oder kleine Umwandlungsarbeiten
  • straightquote: wandelt typografische Anführungszeichen in normale gerade Anführungszeichen um, um Probleme mit Anführungszeichen im Code zu vermeiden und die Dateigröße zu verringern
  • markdownquote: setzt vor jede Zeile ein > und erzeugt so ein Markdown-Zitat
  • length: gibt die Länge einer Eingabezeichenkette zurück (kann wc -c ersetzen)
  • jsonformat: formatiert JSON-Daten hübsch
  • uppered/lowered: wandeln Zeichenketten in Groß- bzw. Kleinbuchstaben um
  • nato bar: wandelt eine Eingabezeichenkette in den NATO-Buchstabiercode um (Bravo Alfa Romeo usw.)
  • u+ 2025: zeigt Name und Symbol eines Unicode-Zeichens an
  • snippets foo: lädt eine bestimmte Kurzformulierung aus einem persönlichen Snippet-Wörterbuch
    • snippet arrow ergibt den Pfeil →, snippet recruiter eine Vorlagen-Nachricht wie „not interested“

REPL-Starter

  • Inspiriert von Rubys irb lassen sich REPLs für verschiedene Sprachen schnell starten:
    • iclj: Clojure
    • ijs: Deno (oder Node, falls nicht vorhanden)
    • iphp: PHP
    • ipy: Python
    • isql: SQLite (im In-Memory-Modus aus Bash)

Skripte für Datum und Uhrzeit

  • hoy: gibt das aktuelle Datum im ISO-Format aus (Beispiel: 2020-04-20), nutzbar etwa als Präfix für Dateinamen
  • timer 10m: Zeit-Timer (z. B. 10 Minuten), sendet bei Ablauf einen Ton und eine OS-Benachrichtigung
  • rn: nutzt date und cal, um aktuelle Uhrzeit und Monatskalender gut lesbar auszugeben

Audio-, Video- und Bildverarbeitung

  • ocr: extrahiert unter macOS Text aus Bilddateien (soll später erweitert werden)
  • boop: akustische Benachrichtigung je nach Erfolg oder Fehlschlag des letzten Befehls (praktisch etwa nach Testläufen)
  • sfx: spielt bestimmte Effekt-Sounddateien (.ogg) ab, in Kombination mit boop und timer
  • tunes: spielt Audiodateien mit mpv ab (mit Shuffle-Unterstützung)
  • pix: zeigt Fotos mit mpv an
  • radio: Schnellstarter für bevorzugte Internetradiosender
  • speak: entfernt Markdown aus von stdin gelesenem Text und wandelt ihn per Sprachsynthese (TTS) in Sprache um
  • shrinkvid: komprimiert Videodateien mit ffmpeg
  • removeexif: entfernt EXIF-Daten aus JPEGs; Unterstützung weiterer Formate ist geplant
  • tuivid: schaut Videos direkt im Terminal; in der Praxis selten genutzt, aber eine ungewöhnliche Funktion

Prozessverwaltung

  • each: Alternative zu xargs oder find ... -exec, um komplexe Befehle einfacher auszuführen
  • running foo: sucht laufende Prozesse anhand eines Stichworts (PID, Befehl usw.) und gibt sie in gut lesbarer Form aus
  • murder: ein Wrapper um kill, der schrittweise von sanften Signalen bis zum erzwungenen Beenden eskaliert. Verhindert Fehler beim Beenden von Programmen
  • waitfor $PID: wartet, bis die angegebene PID beendet ist, und hält den Zustand dabei aktiv
  • bb my_command: startet einen Befehl in einem echten Hintergrundmodus, geeignet etwa für Daemons
  • prettypath: gibt $PATH zeilenweise und übersichtlich aus (nützlich beim Debugging)
  • tryna my_command/trynafail my_command: wiederholt einen Befehl bis zum Erfolg (run until success) bzw. bis zum Fehlschlag (run until fail), vielseitig einsetzbar etwa für Netzwerkautomatisierung

Tools für die Schnellreferenz

  • emoji: sucht und gibt Emojis anhand von Schlüsselwörtern aus
  • httpstatus: gibt eine Liste aller HTTP-Statuscodes aus und erklärt bestimmte Codes
  • alphabet: gibt das komplette englische Alphabet in Klein- und Großbuchstaben aus (überraschend oft nützlich)

Systemverwaltung

  • theme 0/theme 1: ändert das systemweite Theme (dunkel/hell), auch in Verbindung mit Vim, Tmux usw.
  • sleepybear: versetzt das System in den Ruhezustand (macOS, Linux)
  • ds-destroy: löscht .DS_Store-Dateien rekursiv, nützlich beim Aufräumen von Ordnern unter macOS

Sonstiges

  • catbin foo: zeigt den Quellcode einer Datei im PATH direkt an
  • notify: sendet Benachrichtigungen auf OS-Ebene, etwa wenn lang laufende Aufgaben abgeschlossen sind
  • uuid: erzeugt eine UUID der Version 4

Fazit

  • Die in diesem Artikel vorgestellten Skripte sind Werkzeuge, die der Autor tatsächlich häufig nutzt
  • Selbstgeschriebene Skripte für Kurzbefehle sind sehr wirksam, um Arbeitsabläufe effizienter zu machen, Fehler zu vermeiden und die Produktivität zu steigern
  • Es wird empfohlen, auch eigene Automatisierungs-Skripte zu erstellen und aktiv zu nutzen

2 Kommentare

 
GN⁺ 2025-10-23
Hacker-News-Kommentar
  • Der Befehl trash a.txt b.png verschiebt die Dateien a.txt und b.png in den Papierkorb; unterstützt auf Mac und Linux. Meine frühere Methode arbeitete die Dateien nacheinander ab, sodass man für jede Datei das Löschgeräusch hörte und mit ⌘Z im Finder nur die letzte Datei wiederherstellen konnte. Man könnte das verbessern, aber ehrlich gesagt ist es bequemer, einfach den offiziell in macOS eingebauten Befehl trash zu verwenden. Da ich den Finder nicht nutze, gibt es weder Geräusch noch ⌘Z-Wiederherstellung, aber dafür ist es schneller und die Funktion „Put Back“ funktioniert auch. Und fürs Pretty-Printing von JSON lässt sich statt node mit jq dieselbe Aufgabe mit viel kürzerem Code lösen, und auf aktuellem macOS ist jq bereits vorinstalliert. Dasselbe gilt fürs Ausgeben von UUIDs: Wenn man eine v4-UUID braucht, ist uuidgen die naheliegende Wahl (siehe Manpage)

    • Oft ist es besser, eingebaute Funktionen zu nutzen als eigene Skripte. In vim kann man zum Beispiel statt markdownquote einfach mit ctrl-v die erste Spalte markieren, i> eingeben und dann Escape drücken. Das ist kürzer und effizienter. Ich frage mich, warum u+ 2025 ñ zurückgibt, denn der eigentliche Unicode-Wert ist U+00F1. Und catbin foo ist dasselbe wie cat "$(which foo)". Wenn man zsh benutzt, ist cat =foo kürzer und mächtiger. In zsh funktioniert nach = auch Autovervollständigung, sodass man das selbst bei langen Befehlen sicher verwenden kann. Ich nutze oft Dinge wie file =firefox, vim =myscript.sh

    • Ich vermute, der Autor kannte uuidgen einfach nicht. Genau deshalb ist es wichtig, solches Wissen oder solche Konfigurationen zu teilen — dabei werden immer meine blinden Flecken sichtbar

    • Python kann JSON ebenfalls standardmäßig pretty-printen

      $ echo '{ "hello": "world" }' | python3 -m json.tool
      {
        "hello": "world"
      }
      
    • Danke für den Hinweis zu trash. Ich habe bisher AppleScript in der Art von tell app \"Finder\" to move {%s} to trash verwendet, um mehrere Dateien in den Papierkorb zu verschieben

    • Als Alternative zu rm und trash kann ich auch rip empfehlen Link zum rip-Projekt

  • Der Lebenszyklus von Entwicklern ist wirklich faszinierend. Am Anfang nutzt man nur eine ganz normale Shell-Umgebung, dann schreibt man nach ein, zwei Jahren hunderte Zeilen Skripte und bash-Aliase. Jetzt, nach 15 Jahren, versuche ich im Gegenteil, möglichst nur die Standard-Shell zu verwenden, gar keine Aliase zu nutzen und komplexere Dinge in Python oder Go zu erledigen

    • Ich glaube, dieser Trend kommt weniger aus irgendeiner Erleuchtung als einfach aus Faulheit (ich sage das, weil ich genau dasselbe mache). Durch Kollegen, die tief in ihre Custom-Umgebungen einsteigen, lerne ich aber ständig neue Tools kennen, und zuletzt habe ich auch Dinge wie atuin und fzf unter Linux ergänzt

    • Ich schreibe Aliase und Funktionen in meine dotfiles, um häufig genutzte Befehle festzuhalten und mir zu merken. Mein Set oft genutzter Werkzeuge aktualisiere ich laufend, und der Umzug auf eine neue Workstation ist ebenfalls einfach

    • Früher, als ich nur einen einzigen nix-Rechner hatte, wollte ich viel stärker anpassen. Heute benutze ich mehrere Geräte gleichzeitig, installiere nur die nötigen Pakete und halte die Umgebungen dadurch einheitlich

    • Auch etwas, das in Python geschrieben ist, nenne ich weiterhin ein Script. Ich finde nicht, dass der Begriff Script nur für Shell-Skripte gilt

    • Wenn ich heute mit jungen Engineers arbeite und sehe, wie sie mehrere dotfiles verwenden, denke ich: „So habe ich das früher auch gemacht, und es war mühsam.“ Inzwischen wähle ich Tools selektiv aus und passe nur das an, was nötig ist. Den Stil anderer respektiere ich dabei ebenfalls

  • Ich liebe es, solche Beiträge mit praktischen Tipps auf HN zu finden. Mich interessiert, wie andere Entwickler tatsächlich arbeiten und was ich davon lernen und übernehmen kann. Anfangs denke ich oft: „Brauche ich vermutlich nicht“, aber wenn eine Aufgabe einfacher wird, entsteht daraus oft schon ein neuer Workflow. Deshalb probiere ich es erstmal aus und behalte, was passt. Ich mag auch den Stil des Originalbeitrags — dass die tatsächliche Nutzungshäufigkeit mit angegeben wurde, ist wirklich praktisch. Einfache Aufgaben erledige ich oft einfach, indem ich die Browser-Devtools öffne und etwas JavaScript ausführe. (Zum Beispiel, um einen String in Kleinbuchstaben umzuwandeln)

    • Es wäre interessant, eine echte cost-benefit analysis zu machen, also die Zeit nach der Methode des Autors und nach meiner Methode gegeneinanderzustellen, inklusive der Kosten für Erstellen, Merken, Nachschlagen und Migrieren der Skripte

    • Dieses Bild mit einer Bash-Shortcut-Cheatsheet hilft enorm

  • Statt eines line-Skripts ist die Ausgabe bestimmter Zeilen mit sed einfacher

    sed -n 2p file
    

    Damit lässt sich die zweite Zeile ausgeben. Mehrere Zeilen gehen ebenso mit

    sed -n 2,4p file
    

    und sind damit vorteilhafter als ein line-Skript

    • Ich muss oft mehrere sed-Befehle kombinieren. Dann muss ich jedes Mal den ersten sed-Befehl weiter anpassen. Manchmal braucht man vor sed auch noch grep, aber wenn man es mit cat, tail und head aufteilt, lassen sich die einzelnen Funktionen modularer einsetzen. Das entspricht der Unix-Philosophie, nach der jedes Werkzeug genau eine Sache tun soll
  • Ich habe ein paar einfache Skripte, die ich oft benutze. Zum Beispiel:

    #!/usr/bin/env bash
    # ~/bin/,dehex
    
    echo "$1" | xxd -r -p
    
    #!/usr/bin/env bash
    # ~/bin/,ht
    
    highlight() {
      # Farben: 30=Schwarz, 31=Rot, 32=Grün, ...
      escape=$(printf '\033')
      sed "s,$2,${escape}[$1m&${escape}[0m,g"
    }
    
    if [[ $# == 1 ]]; then
      highlight 31 $1
    elif [[ $# == 2 ]]; then
      highlight 31 $1 | highlight 32 $2
    elif [[ $# == 3 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3
    elif [[ $# == 4 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3 | highlight 36 $4
    fi
    

    Eigene Skripte stelle ich mit einem führenden , (Komma) an den Anfang, damit ich schnell dorthin wechseln kann. Ich halte es auch für sinnvoll, regelmäßig Statistiken über meine eigenen Skripte aus der Historie zu erstellen und diejenigen aufzuräumen, die ich nicht mehr benutze

  • Ich habe es noch nicht verallgemeinert, aber mit einem unmv-Skript arbeite ich ziemlich bequem

    #!/bin/sh
    if test "$#" != 2
    then
      echo 'Error: unmv must have exactly 2 arguments'
      exit 1
    fi
    exec mv "$2" "$1"
    
  • Es gibt viele gute Tipps, aber ich lerne und nutze meistens Standard-Utilities (sed, awk, grep, xargs usw.). Der Grund ist, dass ich auf vielen verschiedenen Systemen arbeite und meine persönlichen Skripte und Aliase dort meistens nicht installiert sind. Mit Standard-Utilities kann man fast alles erledigen

    • Stimme ich voll zu. Man greift automatisch zu Standards, damit man überall arbeiten kann. Wirklich gute Tools werden aber irgendwann standardmäßig mitinstalliert oder lassen sich leicht per apt-get installieren. Ich halte gepflegte Pakete für wünschenswerter als eine Sammlung persönlicher Skripte
  • Ich teile mal mein Lieblingsskript zum Entpacken

    # ex - archive extractor
    # Nutzung: ex <Datei>
    function ex() {
      if [ -f $1 ] ; then
      case $1 in
        *.tar.bz2) tar xjf $1 ;;
        *.tar.gz) tar xzf $1 ;;
        *.tar.xz) tar xf $1 ;;
        *.bz2) bunzip2 $1 ;;
        *.rar) unrar x $1 ;;
        *.gz) gunzip $1 ;;
        *.tar) tar xf $1 ;;
        *.tbz2) tar xjf $1 ;;
        *.tgz) tar xzf $1 ;;
        *.zip) unzip $1 ;;
        *.Z) uncompress $1;;
        *.7z) 7z x $1 ;;
        *) echo "'$1' cannot be extracted via ex()" ;;
      esac
      else
        echo "'$1' is not a valid file"
      fi
    }
    
    • Ich würde gern auch das Gegenstück zum Komprimieren bauen

    • Ich benutze dtrx, das automatisch in einen Ordner entpackt, was ich sehr praktisch finde

    • Ich finde aunpack bequemer

    • Wirklich elegant

    • Mit inotify und einem systemd-User-Service wäre das noch eine Stufe weiter. Es gibt bereits eine Version davon als Paket. Selbst gebaut wirkt es ein wenig wie ein quadratisches Rad (Neu-Erfindung)

  • Ich habe zwei Funktionen, die ich immer zum Encodieren oder Zuschneiden von mp4 benutze. Durch die Flags ist die Kompatibilität in verschiedensten Umgebungen wie WhatsApp oder mobilem Discord maximal hoch

    ffmp4() {
      input_file="$1"
      output_file="${input_file%.*}_sd.mp4"
    
      ffmpeg -i "$input_file" -c:v libx264 -crf 33 -profile:v baseline -level 3.0 -pix_fmt yuv420p -movflags faststart "$output_file"
    
      echo "Compressed video saved as: $output_file"
    }
    
    ffmp4 foo.webm  # konvertiert zu foo_sd.mp4
    
    fftime() {
      input_file="$1"
      output_file="${input_file%.*}_cut.mp4"
      ffmpeg -i "$input_file" -c copy -ss "$2" -to "$3" "$output_file"
    
      echo "Cut video saved as: $output_file"
    }
    
    fftime foo.mp4 01:30 01:45  # erzeugt foo_cut.mp4
    

    fftime schneidet schnell, ohne das Original neu zu encodieren, kann aber je nach Video leichte Probleme verursachen (z. B. dass es nicht abspielbar ist). Wenn man neu encodieren will, entfernt man einfach -c copy

  • Wenn ich Aliase oder Funktionen erstelle und teste, ist es praktisch, ~/.zshrc sofort neu zu laden, deshalb nutze ich diesen Alias

    alias vz="vim ~/.zshrc && . ~/.zshrc"
    

    Und auf dem Mac nutze ich für das Greppen in docx-Dateien diese Funktion

    docgrep() {
      mdfind "\"$@\"" -onlyin /Users/xxxx/Notes 2> >(grep --invert-match ' [UserQueryParser] ' >&2) | grep -v -e '/Inactive/' | sort
    }
    

    Außerdem verwende ich auf meinem Mac zum Anonymisieren der Zwischenablage, bevor ich Inhalte in öffentliche Kanäle wie ChatGPT oder den internen Slack einfüge, die folgende Funktion fürs Debugging. Wenn die Funktion läuft, zeigt sie die neu umgewandelte Zwischenablage auf stdout an, sodass man prüfen kann, ob etwas übersehen wurde

    anonymizeclipboard() {
      my_user_id=xxxx
      account_ids="1234567890|1234567890" #regex
      corp_words="xxxx|xxxx|xxxx|xxxx|xxxx" #regex
      project_names="xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pii="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      hostnames="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pbpaste | sed -E -e 's/([0-9]{1,3})\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/\1.x.x.x/g' \
      -e "s/(${corp_words}|${project_names}|${my_user_id}|${pii}|${hostnames})/xxxx/g" -e "s/(${account_ids})/1234567890/g" | pbcopy
      pbpaste
    }
    alias anon=anonymizeclipboard
    
    • Das ist wirklich großartig. So etwas kommt oft vor, und ich hatte bisher keine gute Methode dafür
 
krepe90 2025-10-24

Ich muss auch an den Beitrag auf GeekNews denken: Ask GN: Gibt es Shell-Snippets, die ihr häufig verwendet?