bashshellxargsdeclare

Why does ''xargs bash -vc "$(declare -f {})"'' not work?


Bash 3.2.57 running on OSX.

  1. Following displays the function definition as expected.
declare -f my_bash_function
  1. Following works as well but only with -v flag.
bash -vc "$(declare -f my_bash_function)"
  1. Following does not work as I would expect. It displays nothing.
echo "my_bash_function" | xargs -I{} bash -vc "$(declare -f {})"
  1. However, if the placeholder is replaced with the function name, it works.
echo "my_bash_function" | xargs -I{} bash -vc "$(declare -f my_bash_function)"
  1. Using single quotes, simply displays the command itself even if the function doesn't exit. Which means it isn't evaluating and/or executing it.
echo "my_bash_function" | xargs -I{} bash -vc "$(declare -f {})"
$(declare -f my_bash_function)
declare -f my_bash_function

Please explain why number (3) does not behave as expected?


Solution

  • The reason you need -v in #2 is because you're using command substitution. So it executes declare -f my_bash_function, which outputs the function definition. This is then substituted into the bash -c argument, which makes the subshell execute the code that defines the function. When you add -v it prints the commands that it's executing, so you see the function definition.

    The reason that #3 doesn't work is that the command substitution $(declare -f {}) is being performed by the original shell, not the shell started by xargs. So it's looking for a function named {}, which doesn't exist.

    It seems like you're trying to use $(declare -f my_bash_function) to export the function to the subshell. You can use export -f my_bash_function to put the function in the environment, and it will be exported automatically.