9

I have an org-mode file that contains a BASH script in an org-babel source block. I would like to pass environmental variable values to it through :var.

something like:

#+begin_src sh :var VAR1="~/foo"
  mkdir ${VAR1}/test

or:

#+begin_src sh :var VAR1="${MY_ENV_VAR}/foo"
  mkdir ${VAR1}/test

When I run the blocks with C-c C-c, they complain about not being able to find the ${VAR1} directory.

I think ${VAR1} is not being expanded properly inside the bash shell.

What's the right way to do it?

Enze Chi
  • 1,410
  • 12
  • 28
  • Try `#+begin_src sh :var VAR1=(substitute-in-file-name "$MY_ENV_VAR/foo")`. – Tobias Jun 22 '15 at 08:06
  • @Tobias Thanks for your reply. I tried you solution. It works environment variable, such as, `${HOME}`, but still doesn't work with `~`. – Enze Chi Jun 23 '15 at 12:09
  • 2
    Try `#+begin_src sh :var VAR1=(expand-file-name (substitute-in-file-name "$MY_ENV_VAR/foo"))`. This is ugly, I have to admit. – Tobias Jun 23 '15 at 12:16

1 Answers1

2

First Thanks @Tobias for the answer which solved my problem. But after more test, I just found that still has small issue about the solution if use expand-file-name.

For example, if your environment variable is just string instead of real file name or directory (like ${USER}), the expand-file-name would add some directory before that and that may not what your want. So you have to know what's the variable would look like before you code it.

To solve this problem, I just write a simple function which only apply expand-file-name if the result of subsitute-in-file-name start with ~.

Function:

(defun ec-expand-env (str)
  "Expand the environment variables in the STR."
  (let ((expanded-str (substitute-in-file-name str)))
    (if (string-prefix-p "~" expanded-str)
        (expand-file-name expanded-str)
      expanded-str)
    )
  )
Enze Chi
  • 1,410
  • 12
  • 28