Org-mode code blocks with long-running processes

By on

When exporting an Org document to HTML, Org-mode’s exporter can run shell commands and print their output to the exported page.

For example, when writing an article about Ruby, it might be useful to show how to start a web server and display the output printed to the command line:

ruby server.rb
Server running on http://localhost:4567...

In the Org file, that code block might look like this:

Finally, start the server by running =ruby server.rb=:

#+header: :exports both
#+header: :results output
#+begin_src shell
  ruby server.rb
#+end_src

This example includes the command to start the server (ruby server.rb) and sets the :exports header to export both the input command and the results of running it.

However, because the server is a long-running process, exporting this document causes the exporter to hang. It’s waiting for a result from the command which never comes because the server remains open to connections until it’s quit.1

To start a long-running process and quit it after some time has passed on the command line, use the timeout utility to automatically kill the process after a predefined delay:

timeout 1 ruby server.rb; echo "Done!"
Server running on http://localhost:4567...
Done!

To translate this to an Org code block, use a :prologue and :epilogue to add the timeout without showing it in the exported file. The :prologue prefixes the command with the call to the timeout utility and the :epilogue appends : to the command to make sure the block returns a zero exit code:

Finally, start the server by running =ruby server.rb=:

#+header: :exports both
#+header: :results output
#+header: :prologue timeout 1
#+header: :epilogue ":"
#+begin_src shell
  ruby server.rb
#+end_src

Exporting this example starts the server, then waits for a second before quitting the process. Then, both the input block—which shows the command to start the server—and the output block—showing the server’s output—are exported to the HTML document:

ruby server.rb
Server running on http://localhost:4567...


1

To stop a stuck foreground process in Emacs (like the exporter that accidentally called a slow or continuous program), run C-g to send an exit signal to the code that’s being executed.