4

TL;DR: How do I get the stderr of my source block to be part of the #+RESULTS block, without changing the contents of the block? I can only get stdout to appear.


[Long and winding explanation]

While writing this question I found a solution/reason to it not working. Since I spent quite some time on it, I thought I'd still post it.

Hey there!

I'm relatively new to emacs and org mode especially. Last month, I started writing my bachelor's thesis for applied computer science using org mode (based on dangom's template).

In the thesis, I use org-src blocks to demonstrate stuff. In this case, I've set up an example to demonstrate warnings from a C Compiler:

#+CAPTION: A simple C-Program without errors, but with a Code Smell
#+NAME: qc:c-code
#+ATTR_LATEX: :placement [H]
#+BEGIN_SRC C :tangle ../sourcecodes/foo.c
// foo.c
#include <stdio.h>

int main() {
    int i=10;
}
#+END_SRC

As you can see, this program is stored in a seperate sourcecodes folder:

├── backmatter
├── frontmatter
├── images
├── library.bib
├── literatur
├── mainmatter
│   └── 03-analysis.org <- This is where I am
├── sourcecodes
│   ├── foo
│   └── foo.c <- and here goes the program
└── thesis

Now, I wish to build that file.

#+CAPTION: ...
#+NAME: qc:c-code-build
#+ATTR_LATEX: :placement [H]
#+BEGIN_SRC sh :results output :dir ../sourcecodes
gcc foo.c -Wall -o foo
#+END_SRC

In this example, I use the dir header to change the directory for execution of the code.

When run in a terminal, this results to this:

foo.c: In function 'main':
foo.c:5:9: warning: unused variable 'i' [-Wunused-variable]
    5 |     int i=10;
      |         ^


This is what I would expect. In emacs, it results to this:

#+RESULTS: qc:c-code-build

Whereas this

#+CAPTION: ...
#+NAME: qc:c-code-build
#+ATTR_LATEX: :placement [H]
#+BEGIN_SRC sh :results output :dir ../sourcecodes
ls
gcc --version
gcc foo.c -Wall -o foo
ls
#+END_SRC

returns that:

#+RESULTS: qc:c-code-build
: foo.c
: gcc (GCC) 9.3.0
: Copyright (C) 2019 Free Software Foundation, Inc.
: This is free software; see the source for copying conditions.  There is NO
: warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
: 
: foo
: foo.c

Now, obviously this is not a real problem - just copy and paste the desired output into a src block your own.

I would just like to know if I'm missing something super obvious.

Other stuff I've tried/noticed:

  • Using shell instead of sh
  • results: output replace
  • :exports both
  • created a minimal example, which does not load anything from the template
  • tried to use scimax (and failed, since by default it doesn't contain the org-babel-execute function for sh/shell)
  • some Buffer once gave me errors (Error Output or something)

Now, as promised, the reason:

Org-mode shell source blocks do not capture stderr

My solution for the problem: I don't have a good solution for this as of yet. The solution of John Kitchin suggests use of 2>&1 which writes all stderr to stdout, for example:

#+BEGIN_SRC sh :results output replace :dir ../sourcecodes :exports both
gcc foo.c -Wall -o foo 2>&1
#+END_SRC

But that adds some unnecessary logic to the eye for the reader of the thesis, which is why I'm probably staying with copy-pasting stderr into src-blocks (except someone has a better solution)

  • What's the question? A quick reading gives me the impression that you're providing an answer to your question as part of the question. If so, please don't do that. Pose a straightforward question, if you have one. You can also then pose a straightforward answer to it, if you like. As it stands now, it doesn't seem like you have a real question. – Drew Jul 29 at 22:12
  • 1
    I guess the question is roughly: "how to obtain stderr output without changing the source block content". – Firmin Martin Jul 30 at 3:25
7

Rephrasing and shortening, I guess the question is roughly: "how to obtain stderr output without changing the source block content?"

By skimming the comments section of the John Kitchin's post, adding

#+PROPERTY: header-args:sh :prologue "exec 2>&1" :epilogue ":"

globally, at the top of the file, should do the job (it works in my side).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.