0

I have a function like this

function test(){
   local param1=${1}
   local param2=${2}
   echo "Hey ${param1} ${param2}"
}

And then, in another part of the script I have this

echo ${command}
$(command)
echo "Completed"

The output of that execution is

test param1 param2
Completed

So, as you can see, the function test was not executed.

I was looking a way to do that if possible in my shell script.

  • `command` is a shell builtin which does nothing when called without any args (try running `command` at the command prompt); `$( command )` says to run the (builtin) `command` in a subshell ... which still does nothing; to reference the variable `command` try `$( $command )` ... not saying your code will work as expected but it should get you further along in the process; generally speaking ... naming variables, function and scripts with the same names as builtins and system executables (eg, `test` and `command`) isn't a recommended practice – markp-fuso Aug 02 '22 at 16:21
  • Ok, I saw the response in [this other post](https://stackoverflow.com/questions/33387263/invoke-function-whose-name-is-stored-in-a-variable-in-bash). Sorry. – user17491732 Aug 02 '22 at 16:22
  • BTW, re: `function test() {`, see https://wiki.bash-hackers.org/scripting/obsolete. Modern POSIX-compliant function declaration syntax is just `test() {`; 1980s ksh used `function test {` with no `()`; merging the two gives you the worst of both worlds, as your code is compatible with _neither_ legacy ksh nor baseline POSIX. – Charles Duffy Sep 11 '22 at 01:29
  • Also, using `test` as your function name is probably best avoided, as it shadows the built-in `test` command. – Charles Duffy Sep 11 '22 at 01:30

1 Answers1

0

The good practice for this is described below:

command=(test a b)

echo ${command}
"${command[@]}"
echo "Completed"

The above code will use an array to store the command and the parameters, and it will call the function appropriately.

To specifically fix the expected behavior of your code, you could call the function using ${command} or $command, which is different from $(command). But the preferred practice, and more secure way of doing that is to follow the previous suggestion.

#!/bin/bash

function test(){
   local param1=${1}
   local param2=${2}
   echo "Hey ${param1} ${param2}"
}


command="test a b"

echo ${command}
${command}
echo "Completed"
  • 1
    This works only for _very_ limited cases; one quickly runs into the bugs described in [BashFAQ #50](https://mywiki.wooledge.org/BashFAQ/050). Far safer to store a multi-word command in an array rather than a string. – Charles Duffy Sep 11 '22 at 01:30
  • That is, `command=( test a b )`, then `"${command[@]}"` to run it. That way you can do things like `command=( printf '%s\n' "first line" "second line" )`, and `"${command[@]}"` correctly prints two lines. Try it yourself if you want to see what that does with the string approach; it's not pretty. – Charles Duffy Sep 11 '22 at 01:49
  • (...also, please @-notify me once you've fixed up this answer so it's no longer hitting BashFAQ #50's bugs, and I'll gladly reverse the downvote). – Charles Duffy Sep 11 '22 at 01:50
  • @CharlesDuffy Hello, I've added more information regarding your observations, and I believe it is a more complete answer now. – Luis Cardoso Sep 11 '22 at 02:30
  • Downvote reversed (someone else added another one, but that I can't fix). I do suggest removing the buggy branch of the answer in favor of the robust one, or at least putting the good-practices form first. – Charles Duffy Sep 11 '22 at 02:35
  • @CharlesDuffy The best practice is now being shown earlier. – Luis Cardoso Sep 11 '22 at 03:10
  • Upvoted. That said, when `command` is an array, `echo ${command}` only shows the first word of the command in bash (it shows the whole thing in zsh). `echo "${command[@]}"` shows the whole thing (but without any way of distinguishing between syntactic and literal spaces, so it's a potentially-misleading view); a more accurate rendition for bash 5.0 or newer is `echo "${command[*]@Q}"`. – Charles Duffy Sep 11 '22 at 03:24