Is it possible to have a variable that dynamically evaluates a command in bash?

Viewed 38

Basically, what I want is to have a variable that contains e.g. $(some-command), so that it provides the result of some-command at the time it is expanded.

An example would help clarify what I mean.

Suppose I have some command tell-svn-root which prints to stdout the path of the most recent (i.e. deepest) ancestor of the current directory that contains a subdirectory .svn.

I would love to create a variable SVNROOT that always evaluates to the output of tell-svn-root.

SVNROOT=$(tell-svn-root) in .bashrc won't work because then SVNROOT will have a fixed value (namely the output of tell-svn-root when .bashrc was run).

A function that runs e.g. cd $(tell-svn-root) is also insufficient because I'd like to write commands like cd $SVNROOT/my-app-src.

I know that I can do $(tell-svn-root)/my-app-src, but typing those extra parentheses does slow things down a bit since it involves two characters up on the numbers row of the keyboard rather than just one.

I can't find a good answer for this, so I suspect it might be impossible.

1 Answers

You are correct: Precisely as-given (triggering code to be run whenever a specific variable's value is requested), the request is impossible.

That said, there are some workarounds; for example, you can have a function run every time the prompt is about to be printed (or before every command, if you were to implement a DEBUG trap), which updates your variable at that time.

Obviously, the performance impact is potentially nontrivial, and I would strongly suggest the extra verbosity involved in a function invocation; particularly insofar as safe practices for handling untrusted data are generally quite verbose, bash is not a language safe for use by those enamored with terseness.

update_variables() {
  if [[ $svnroot_for_PWD != "$PWD" ]]; then
    svnroot=$(tell-svn-root)
    svnroot_for_PWD=$PWD
  fi
}
PROMPT_COMMAND=update_variables

With respect to variable naming convention -- all-caps names are reserved for variables meaningful to the shell and other POSIX-defined tools, whereas lowercase names are guaranteed safe to use by user-defined code. See the relevant specification at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html, keeping in mind that environment and shell variables share the same namespace.

Related