CommunitySchreiben & Editierengithub.com

Shell- & Bash-Codeblöcke in Org Babel

Vollständiger Leitfaden für Systemautomatisierung, DevOps, Remote-Ausführung und Shell-Scripting (Bash, Zsh, Fish, Dash, Sh) mit Org Babel.

Was ist Shell- & Bash-Codeblöcke in Org Babel?

Dieses Skill beschreibt die Integration von Shell- und Bash-Codeblöcken in Org Babel, einem vielseitigen Werkzeug, das Org-Mode-Dokumente in interaktive DevOps-Notizbücher, Runbooks und Systemverwaltungskonsolen verwandelt. Es ermöglicht die lokale Ausführung, Hintergrundverarbeitung und Remote-Server-Verwaltung über SSH via TRAMP. Das Skill deckt alle gängigen Unix- und POSIX-Shells ab: Bash, Zsh, Sh, Fish, Dash, Csh, Ksh und Ash. Entwickler profitieren von drei Ausführungsmodi – isolierte Subshells für saubere Umgebungen, persistente interaktive Sitzungen für zustandsbehaftete Abläufe und asynchrone Blockausführung für langlaufende Aufgaben ohne Emacs-Blockierung. Spezielle Header-Argumente wie `:stdin` für Pipe-Daten, `:cmdline` für Parameterübergabe und `:shebang` für saubere Skriptausführung erweitern die Kontrolle. Das Skill ist plattformunabhängig und funktioniert mit jeder Emacs-Distribution, die Org Babel unterstützt. Es eignet sich ideal für Continuous Deployment, Cluster-Verwaltung und komplexe Automatisierungsworkflows direkt aus dem Editor.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pwquint24/org-babel-agent-skills/tree/HEAD/skills/org-babel-shell

Installed? Explore more Schreiben & Editieren skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Shell- & Bash-Codeblöcke in Org Babel?

Org Babel bietet umfassende Unterstützung für Shell-Scripting in Unix- und POSIX-Shells: Bash, Zsh, Sh, Fish, Dash, Csh, Ksh und Ash.

Shell-Blöcke verwandeln Org Mode in ein interaktives DevOps-Notizbuch, Runbook und eine Systemverwaltungskonsole, die lokale Ausführung, asynchrone Hintergrundverarbeitung und Remote-Server-Verwaltung über SSH mittels TRAMP ermöglicht.


1. Anforderungen & Konfiguration

1.1 Emacs-Konfiguration

Anders als bei anderen Babel-Sprachen, die separate Module benötigen, werden alle Shells durch eine einzige Babel-Bibliothek (ob-shell) gesteuert. Es ist lediglich (shell . t) in org-babel-load-languages erforderlich:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (shell      . t)))

(Hinweis: Vor Org 8.2 hieß dies sh. Verwenden Sie in allen modernen Org-Versionen shell).

1.2 Shell festlegen

Geben Sie den genauen Namen der Shell-Binärdatei als Block-Sprach-Tag an (#+BEGIN_SRC <shell>):

# Bash:
#+BEGIN_SRC bash
  echo "Running in $BASH_VERSION"
#+END_SRC

# Zsh:
#+BEGIN_SRC zsh
  echo "Running in Zsh $ZSH_VERSION"
#+END_SRC

# POSIX / Dash (schnellere, schlanke Ausführung):
#+BEGIN_SRC dash
  echo "Running in dash"
#+END_SRC

# Fish shell:
#+BEGIN_SRC fish
  set greeting "Hello from fish"
  echo $greeting
#+END_SRC

Die angegebene Shell-Binärdatei muss über Ihren System-$PATH erreichbar sein.


2. Ausführungsmodi: Isoliert, Sitzung & Asynchron

2.1 Isolierte Subshell (Standard, :session none)

Jeder Block läuft in einem frischen, temporären Subshell-Prozess. Umgebungsvariablen und Arbeitsverzeichnisse werden nicht übernommen:

#+BEGIN_SRC bash :results output
  echo "PID: $$"
  export WORKSPACE="/tmp/build"
#+END_SRC

#+BEGIN_SRC bash :results output
  # $WORKSPACE ist hier leer, da dieser Block in einem neuen Subshell-Prozess läuft:
  echo "PID: $$, WORKSPACE: $WORKSPACE"
#+END_SRC

2.2 Interaktive Sitzungen (:session <name>)

Läuft innerhalb eines persistenten Emacs-comint-Puffers (z. B. *dev-session*). Variablen, Funktionen und Arbeitsverzeichnisse bleiben über mehrere Blöcke hinweg erhalten:

#+BEGIN_SRC bash :session *dev-session* :results output
  export CLUSTER_ID="prod-east-01"
  cd /var/log
#+END_SRC

#+BEGIN_SRC bash :session *dev-session* :results output
  # Verwendet den Zustand aus dem vorherigen Block:
  echo "Deploying to $CLUSTER_ID from $(pwd)"
#+END_SRC

#+RESULTS:
: Deploying to prod-east-01 from /var/log

2.3 Nicht-blockierende asynchrone Ausführung (:async yes)

Lang laufende Skripte (Backups, Container-Builds, Modelltraining) frieren Emacs ein, wenn sie synchron ausgeführt werden. Fügen Sie :async yes hinzu, um sie im Hintergrund auszuführen, ohne den Editor zu blockieren!

Regeln:

  1. :async erfordert :session <name>.
  2. Während der Ausführung fügt Babel einen temporären UUID-Token im #+RESULTS:-Block ein.
  3. Sobald die Ausführung im Hintergrund abgeschlossen ist, wird die UUID automatisch durch die Standardausgabe des Befehls ersetzt.
#+BEGIN_SRC bash :session *bg-job* :async yes :results output
  echo "Starting heavy database backup at $(date)..."
  sleep 5
  echo "Backup finished successfully at $(date)!"
#+END_SRC

#+RESULTS:
: Starting heavy database backup at Sun May 18 14:00:00 UTC 2025...
: Backup finished successfully at Sun May 18 14:00:05 UTC 2025!

Um synchron in einer Sitzung auszuführen, übergeben Sie :async no.


3. Shell-spezifische Header-Argumente

Org Babel bietet drei einzigartige Header-Argumente, die speziell auf Shell-Operationen zugeschnitten sind:

3.1 :stdin <element-name> (Standard-Eingabe)

Leitet benannte Org-Elemente (Tabellen, Rohtext oder Ergebnisse anderer Code-Blöcke) an die Standardeingabe des Shell-Befehls weiter:

# Rohtext-Eingabe:
#+NAME: raw_server_payload
{"node": "alpha", "cores": 8, "status": "active"}

# Übergibt die Daten direkt an jq:
#+BEGIN_SRC bash :stdin raw_server_payload :results output
  jq -r '.node + " has " + (.cores|tostring) + " cores"'
#+END_SRC

#+RESULTS:
: alpha has 8 cores

(Hinweis: Blöcke mit :stdin werden in einer temporären Subshell ausgewertet und ignorieren :session).

3.2 :cmdline <args> (Kommandozeilen-Argumente)

Übergibt Positionsargumente ($1, $2, $@) an den Skriptkörper:

#+BEGIN_SRC bash :cmdline "staging" 8080 :results output
  ENV="$1"
  PORT="$2"
  echo "Starting server on port $PORT in $ENV mode..."
#+END_SRC

#+RESULTS:
: Starting server on port 8080 in staging mode...

⚠️ Sicherheitswarnung: :cmdline-Argumente werden von der Host-Shell direkt expandiert. Übergeben Sie keine unsicheren oder nicht maskierten Zeichenfolgen, um eine Befehlsinjektion zu vermeiden.

3.3 :shebang <directive> (Eigenständige Skripte & saubere Ausgabe)

Erzwingt, dass der Block in eine temporäre ausführbare Datei geschrieben und über ihre Shebang-Direktive ausgeführt wird:

#+BEGIN_SRC bash :shebang "#!/usr/bin/env bash" :results output
  for i in {1..3}; do
      echo "Step $i"
  done
#+END_SRC

Warum :shebang essenziell ist: In mehrzeiligen :session-Blöcken ohne Shebang werden Zeilen zeilenweise an die interaktive Shell gesendet, was zu störenden Eingabeaufforderungen (z. B. bash-5.1$ ) in Ihren Ergebnissen führen kann. Die Angabe von :shebang oder die Ausführung ohne Sitzung liefert vollständig saubere Ausgaben.


4. Remote-Server-Verwaltung via TRAMP (:dir)

Sie können Befehle auf Remote-Servern, virtuellen Maschinen oder Docker-Containern ausführen, indem Sie einen TRAMP-Pfad in :dir angeben:

:dir /ssh:<user>@<host>:<remote-path>
:dir /docker:<container-id>:<path>
:dir /sudo::/etc

Beispiel: Remote-Sysadmin-Workflow

# Festplattennutzung und Speicher auf einem Remote-Server prüfen:
#+BEGIN_SRC bash :dir /ssh:[email protected]:/tmp :results output
  hostname
  uptime
  df -h / | awk 'NR==2 {print "Root Disk Usage: " $5}'
#+END_SRC

#+RESULTS:
: bastion.example.com
: 14:22:05 up 42 days,  3:18,  1 user,  load average: 0.12, 0.08, 0.05
: Root Disk Usage: 48%

Remote-Sitzungen

Kombinieren Sie :dir mit :session, um eine aktive SSH-Verbindung über mehrere Blöcke hinweg aufrechtzuerhalten, ohne sich bei jedem Schritt neu zu verbinden:

#+BEGIN_SRC bash :dir /ssh:[email protected]:/home/admin :session *remote-bastion* :results output
  WORKDIR=$(mktemp -d)
  cd "$WORKDIR"
  pwd
#+END_SRC

5. Ergebnisformate & tabellarische Datenextraktion

5.1 Tab-getrennte Ausgabe in Org-Tabelle (:results output table)

Wenn Shell-Befehle tab-getrennte oder strukturierte tabellarische Ausgaben erzeugen, parst Babel sie in native Org-Tabellen:

#+BEGIN_SRC bash :results output table
  printf "PID\tUser\tCommand\n"
  printf "101\troot\tsystemd\n"
  printf "405\tpostgres\tpostgres\n"
  printf "892\tnginx\tnginx: worker\n"
#+END_SRC

#+RESULTS:
| PID | User     | Command       |
|-----+----------+---------------|
| 101 | root     | systemd       |
| 405 | postgres | postgres      |
| 892 | nginx    | nginx: worker |

5.2 Ausgabe in einen Dateilink lenken (:results file :file <path>)

#+BEGIN_SRC bash :results file :file reports/sysinfo.txt
  uname -a > reports/sysinfo.txt
  cat /etc/os-release >> reports/sysinfo.txt
#+END_SRC

#+RESULTS:
[[file:reports/sysinfo.txt]]

6. Variablen & Bash-Arrays übergeben (:var)

6.1 Skalare und Zeichenketten

#+BEGIN_SRC bash :var port=8000 host="localhost" :results output
  echo "Connecting to $host on port $port..."
#+END_SRC

6.2 Bash 1D-Arrays

Bash unterstützt 1D-Array-Parameter, die mit Listensyntax definiert werden:

#+BEGIN_SRC bash :results output :var servers='("web-01" "web-02" "db-01")'
  echo "Total servers: ${#servers[@]}"
  for s in "${servers[@]}"; do
      echo "Pinging $s..."
  done
#+END_SRC

#+RESULTS:
: Total servers: 3
: Pinging web-01...
: Pinging web-02...
: Pinging db-01...

7. Häufige Fallstricke & Sicherheitsempfehlungen

FallstrickeUrsacheLösung
Emacs hängt bei SSH- oder ffmpeg-BefehlBefehl versucht, von der Subshell stdin zu lesenstdin explizit umleiten (</dev/null) oder ssh -n verwenden.
Störende bash-5.1$-Eingabeaufforderungen in ErgebnissenInteraktives zeilenweises Echo in :session:shebang #!/usr/bin/env bash hinzufügen oder außerhalb einer Sitzung auswerten.
Unbeabsichtigte Variablenexpansion in Heredocs<<EOF erlaubt der Shell, $VARS vorzeitig zu expandierenVerwenden Sie das begrenzende Anführungszeichen <<"EOF", um den Text literal zu halten und eine vorzeitige Expansion zu verhindern.
Nicht-POSIX-Syntax schlägt in sh-Blöcken fehl#+BEGIN_SRC sh wird auf /bin/sh abgebildet (oft dash auf Debian/Ubuntu)Verwenden Sie #+BEGIN_SRC bash, wenn Ihr Skript Bashismen verwendet ([[, ((, Arrays).
Befehlsinjektion via :cmdlineShell-Argumente werden wörtlich ausgewertetArgumente sorgfältig maskieren oder Daten stattdessen via :stdin oder :var übergeben.
Asynchrone Blockausgabe erscheint nicht:async yes erfordert eine aktive :sessionGeben Sie immer eine :session <name> an, wenn Sie :async yes verwenden.

8. Vollständiges DevOps-Runbook-Beispiel

#+TITLE: Production Service Health Runbook
#+PROPERTY: header-args:bash :session *runbook* :results output

* Schritt 1: Health-Check-Konfiguration
#+NAME: cluster_nodes
| Hostname        | Role    |
|-----------------+---------|
| prod-app-01.lan | backend |
| prod-app-02.lan | backend |
| prod-db-01.lan  | storage |

* Schritt 2: Cluster-Knoten untersuchen
#+BEGIN_SRC bash :var nodes=cluster_nodes :colnames yes :results output table
  printf "Host\tRole\tStatus\n"
  for row in "${nodes[@]}"; do
      # Parst tab-/leerzeichengetrennte Zeilendaten:
      host=$(echo "$row" | awk '{print $1}')
      role=$(echo "$row" | awk '{print $2}')
      
      # Schnell-Ping-Prüfung:
      if ping -c 1 -W 1 "$host" > /dev/null 2>&1; then
          status="ONLINE"
      else
          status="OFFLINE"
      fi
      printf "%s\t%s\t%s\n" "$host" "$role" "$status"
  done
#+END_SRC

#+RESULTS:
| Host            | Role    | Status |
|-----------------+---------+--------|
| prod-app-01.lan | backend | ONLINE |
| prod-app-02.lan | backend | ONLINE |
| prod-db-01.lan  | storage | ONLINE |

* Schritt 3: Asynchrone Dienstwartung durchführen
#+BEGIN_SRC bash :session *runbook* :async yes
  echo "Initiating rolling cache purge across nodes..."
  sleep 4
  echo "Cache purge completed successfully."
#+END_SRC

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Verwandte Skills