- Nix 61.2%
- Shell 38.8%
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.md | ||
| run-code-inline | ||
run-code-inline
WARNING: This script attempts to execute any code supplied to it. Only use with code that you know to be trustworthy.
Reads text (e.g., Markdown or Asciidoc) from stdin,
echos it to stdout,
simultaneously running any commands
and inserting the output immediately after the command.
This is useful for writing tutorials and software documentation.
Any line that begins with $ is assumed to be a command.
The commands can launch subshells, subsubshells, and so on...
the result should be the same as if you typed the commands at
a terminal.
For example, the following input
The "echo" command writes a message to the screen.
Here is an example of how to use it.
~~~
$ echo "Hello, world!"
$ echo "This is fun, isn't it?"
~~~
would result in the output below.
Note that the echo commands have been executed and the result included in the output.
The "echo" command writes a message to the screen.
Here is an example of how to use it.
~~~
$ echo "Hello, world!"
Hello, world!
$ echo "This is fun, isn't it?"
This is fun, isn't it?
~~~
If you want to run a command without echoing it to the output,
preceed it with $# instead of $.
If the command generates messages that you don't want to include
in the output, redirect stdin (and perhaps stderr) to /dev/null.
However, typically you will use this script to pre-process files
before sending them to a publishing tool such as pandoc or asciidoctor.
In that scenario, you can simply place the commands inside
comments (using the appropriate syntax for the publishing tool).
Your command and any output will be included in the pre-processed
file (which may be useful for debugging), but not in the final output.
By default, bash is used to process commands. If you want to use a different shell, invoke it as your first command.
One way to invoke this script is
run-code-inline < INFILE > OUTFILE 2>&1
However, you may have intentionally included commands that fail,
perhaps to discuss the error messages.
In that case, you probably want the error messages to go to stdout
rather than stderr, as shown in the example below.
run-code-inline < INFILE > OUTFILE 2>&1
Known issue: exit
The exit command will terminate the entire script.
This is a problem if, for example, you want to launch a subshell,
perform some actions, and then exit to the main shell.
Known issue: nix-shell
The nix-shell command doesn't work as expected when
used with this script; subsequent commands are executed outside the
nix shell, typically leading to errors.
For example, the code
$ nix-shell -p cowsay
$ cowsay "moo"
will produce the output below.
$ nix-shell -p cowsay
$ cowsay "moo"
bash: line 4: cowsay: command not found
Before I present a full workaround, note that we can use the --run bash switch.
$ nix-shell -p cowsay --run bash << EOL
$ cowsay "moo"
$ EOL
This produces the output below.
$ nix-shell -p cowsay --run bash << EOL
$ cowsay "moo"
_____
< moo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
$ EOL
For a complete solution, we can hide the workaround using the $#
syntax.
$# echo '$ nix-shell -p cowsay'
$# nix-shell -p cowsay --run bash << EOL
$ cowsay "moo"
$# EOL
This produces the output below.
$ nix-shell -p cowsay
$ cowsay "moo"
_____
< moo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Known issue: Nix commands generating weird characters.
Some Nix commands will generate the byte sequence 0d 1b 5b 4d.
My workaround is to pipe the output through sed 's/\x0d\x1b.\x4b//g'.