0

In my Bash script, I'm generating a string which contains a series of commands. Some of these commands are references to a function defined within this script. That is:

function myfunc() {
...}
}

cmds=`echo "echo hello"; echo myfunc` # contrived, but you get the idea

bash $cmds

Now, running the commands by invoking a new Bash script doesn't work - the function myfunc isn't defined.

Is there a way around this? Either by making the function global somehow, or by making those commands run within the current shell?

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • The `` cmds=`echo foo` `` thing is highly suspicious. Don't execute stuff unless you actually need it, and use `$()` instead of backticks to avoid (some) quoting nightmares. – Mat Apr 21 '15 at 14:55
  • I tried to make clear that that's not the actual source of the commands - it's a `jq` script, fwiw. – Steve Bennett Apr 21 '15 at 14:57
  • [Don't use a string for commands.](http://mywiki.wooledge.org/BashFAQ/050) Use an array and then just expand it normally (unless you need redirections/brace expansion/etc. in which case you need more than that). – Etan Reisner Apr 21 '15 at 15:11
  • Thanks - didn't realise Bash had arrays. Not sure it really works in this situation though. – Steve Bennett Apr 23 '15 at 04:35

2 Answers2

1

There are two ways: either use export -f to export the function, or use eval to execute the commands in the current shell.

user4098326
  • 1,712
  • 4
  • 16
  • 20
1

You can use eval in this case:

doit() { echo "ok"; }
foo="echo a; echo b; doit;"
eval "$foo"

Or output to a temporary script and source that.

Or you could use export -f to export the functions - that's bash-specific though (remember shellshock?).

Mat
  • 202,337
  • 40
  • 393
  • 406
  • Hmm, `eval` doesn't seem to work for a string containing newlines. (Maybe my script wasn't clear, but the variable contains multiple commands separated by newlines.) – Steve Bennett Apr 21 '15 at 15:03