Using literate shell scripts with org-mode and a real terminal

posted on 2023-05-05

I’m using a literate programming style shell scripting since I have found Emacs org-mode. I have wrote countless of maintenance, deployment and even recovery scripts with the additional benefit of much easier to read, than just inline comments, descriptions and explanations of the „why” of the things I have written. I can even easily convert the executable document to a HTML format and send someone else to read-through and possibly even learn from them. One thing I was lacking was to be able to execute those scripts, or parts of them, inside a real interactive terminal as some of the steps from time to time did require a user’s interaction. Previously I were just commenting on it and using copy&paste strategy, but it was inefficient and cumbersome. Then I have stumbled upon ob-tmux, which allows to execute org_src block inside a tmux session and spawns an external terminal emulator at the same time. The downside is the results are not inserted back into org-mode document, they just live inside the terminal window.

In near future I probably will change the sources a little bit to allow operating inside Emacs via vterm (terminal emulator using vterm library) or eat terminal (pure elisp terminal emulator; still have some issues with my ZSH configuration) rather spawning external terminal. This should be straightforward, will probably expand on the execution of ob-tmux--start-terminal-window (ob-tmux:201 1) function at ob-tmux.el:109 to just spawn vterm or eat terminal with the tmux attach command.

Lastly, if you use xface4-terminal rather than gnome-terminal mentioned in ob-tmux documentation, you could be tempted to just replace gnome for xfce4 in the snippets, but that would not work. It requires to replace the -e with -x in org-babel-tmux-terminal-opts variable, as xfce4-terminal is not a drop-in replacement for gnome-terminal in terms of command line options. Here is a snippet from my own init.d to use xfce4-terminal:

(use-package ob-tmux
    ;; Install package automatically (optional)
    :ensure t
    :custom
    (org-babel-default-header-args:tmux
     '((:results . "silent")
       (:session . "default") ;; The default tmux session to send code to
       (:socket  . nil)))     ;; The default tmux socket to communicate with
    ;; The tmux sessions are prefixed with the following string.
    ;; You can customize this if you like.
    (org-babel-tmux-session-prefix "ob-")
    ;; The terminal that will be used.
    ;; You can also customize the options passed to the terminal.
    ;; The default terminal is "gnome-terminal" with options "--".
    (org-babel-tmux-terminal "xfce4-terminal")
    (org-babel-tmux-terminal-opts '("-T" "ob-tmux" "-x"))
    (org-babel-tmux-location "/usr/bin/tmux"))

Either way – if you had the need to execute org-mode shell source blocks inside a interactive terminal, then take a look at ob-tmux.

Happy hacking!

Footnotes:

1

link references the today’s latest commit.