13

I try to pipe the output of one source block to the next source block as standard input. Here an example of what I have so far:

Create stdin data:
#+header: :exports code
#+header: :results output
#+begin_src sh
echo "That goes to the next"
#+end_src

#+name: piped
#+RESULTS:
: That goes to the next 

Use "piped" as stdin:
#+header: :exports results
#+header: :stdin piped
#+header: :results output
#+begin_src sh
VALUE=$(cat)
echo "I got:"
echo "$VALUE"
#+end_src

My problems with this are:

  • I have to manually create the result of the first block by hitting C-c C-c

  • the result must be included in org-buffer (large output not needed otherwise)

  • the result must be named manually

Is there a workaround or better way to do this?

5 Answers 5

12

Here's a simple way to fix your code by naming the src block instead of results:

#+name: piped
#+header: :exports code
#+header: :results output
#+begin_src sh
echo "That goes to the next"
#+end_src

#+RESULTS:
: That goes to the next 

#+header: :exports results
#+header: :stdin piped
#+header: :results output
#+begin_src sh
VALUE=$(cat)
echo "I got:"
echo "$VALUE"
#+end_src

#+results:
: I got:
: That goes to the next
1
  • 1
    Very good, thanks, that really helped.
    – theldoria
    Commented Jun 28, 2016 at 14:37
7

I had a similar use case, and rolled a simple exporter which let me use json-mode for the source/input from stdin:

;;; ob-passthrough.el ---  passthrough evaluator          -*- lexical-binding: t; -*-

;; this ob evaluates the block as ifself, so it can be used as input
;; for another block

(require 'ob)

(defun org-babel-execute:passthrough (body params)
  body)

;; json output is json
(defalias 'org-babel-execute:json 'org-babel-execute:passthrough)

(provide 'ob-passthrough)
;;; ob-passthrough.el ends here

Then, add (passthrough . t) to org-babel-list-langauges, and here it is in action:

#+NAME: json-test
#+BEGIN_SRC json
  {"greet": "hello, world"}
#+END_SRC

#+HEADER: :stdin json-test
#+BEGIN_SRC sh
  jq .greet
#+END_SRC

#+RESULTS:
: hello, world
2
  • 2
    This is super useful. I used this and added another for XML as well.
    – Aaron
    Commented Dec 24, 2020 at 2:34
  • 1
    Amazingly useful! Should really be a part of org-babel! :-) Thanks! Commented Sep 7, 2021 at 12:57
4

Call a src block from another using "noweb" references (see (info "(org) Noweb reference syntax")):

#+name: input
#+header: :exports code
#+header: :results output
#+begin_src sh
echo "That goes to the next"
#+end_src

#+header: :exports results
#+header: :results output :noweb no-export
#+begin_src sh
VALUE=$(<<input>>)
echo "I got:"
echo "$VALUE"
#+end_src

#+results:
: I got:
: That goes to the next
1
  • 1
    That is cool, good to know, thanks. Unfortunately the second source code block really has to use stdin. The use of cat in the shell was only a simple example.
    – theldoria
    Commented Jun 28, 2016 at 14:36
2

Another way to solve this problem is to name the input as an EXAMPLE or a QUOTE block if the input is truly static. Something like this:

#+NAME: some-json
#+BEGIN_QUOTE
{"label": "Hello json"}
#+END_QUOTE

or an EXAMPLE if you prefer:

#+NAME: some-json-2
#+BEGIN_EXAMPLE
{"label": "ehlo json"}
#+END_EXAMPLE

then reference those named blocks in the code you wish to evaluate; here we use the QUOTE example:

#+NAME: the-code
#+HEADER: :stdin some-json
#+BEGIN_SRC shell
jq .label
#+END_SRC

Since the value of the some-json block is static, there is no need to evaluate it. Evaluating the-code block gives:

#+RESULTS: the-code
: Hello json
0

I love Matt Curtis's answer and use it all the time in my personal config.

However I often find I want to parameterize the payload in some way, so I also made this variant that lets you use the source block as a template:

(defun org-babel-execute:$template (body params)
  "Pass BODY through verbatim except for replacing variables defined in PARAMS."
  (let ((var-defs (org-babel--get-vars params)))
    (pcase-dolist (`(,var-name . ,value) var-defs)
      (let ((var (format "$%s" var-name)))
        (setq body (replace-regexp-in-string (regexp-quote var) value body)))))
  body)

(defalias 'org-babel-execute:json 'org-babel-execute:$template)

Then you can do

#+NAME: json-test-template
#+BEGIN_SRC json :var name=""
  {"greet": "hello, $name"}
#+END_SRC

#+NAME: foo-json
#+CALL: json-test-template(name="foo")

#+RESULTS: foo-json
: {"greet": "hello, foo"}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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