Went through this post: Pass arguments to function exactly as-isBut have a slightly different setup:I have 3 bash functions foo, bar, baz. They are setup as follows:foo() {  bar $1}bar() {  var1=$1  var2=$2  echo $var1 test $var2}export ENV_VAR_1=1export ENV_VAR_2=2 3foo ${ENV_VAR_1} ${ENV_VAR_2}I'd expect the output to be: 1 test 2 3But the output is: 1 test 2I get why this happened. bar was executed as follows: bar 1 2 3My question is: how do I get it to execute bar 1 2 3Approaches I tried:foo () {bar $1} # Out: 1 2 3 test. Makes sense since 1 2 3 is interpreted as a single argument.
pass arguments to function as is
bash
This provides a single string as an argument to foo:foo ${ENV_VAR_1} ${ENV_VAR_2}Because $1 is not in quotes, the shell performs word splitting and, consequently, this provides three arguments to bar:bar $1Word splitting is done on any IFS characters in S1.  The original source of those characters is not considered.Simpler exampleLet's define x as:$ x=${ENV_VAR_1} ${ENV_VAR_2}Now, let's print $x:$ printf %s\n $x1 2 3As you can see, $x is interpreted as one argument.  By contrast, consider:$ printf %s\n $x123In the above, word-splitting is performed on $x creating three arguments.Shell strings have no notion of history.  String x has no record of 2 3 being part of one string before x was assigned. String x just consists of 1, space, 2, space, and 3 and word splitting operates on the spaces.Alternative: selecting your own IFSThis produces the output that you want:$ foo() ( IFS=@;  bar $1; )$ foo ${ENV_VAR_1}@${ENV_VAR_2}1 test 2 3In foo, we set IFS to @.  Consequently, all subsequent word splitting is performed using @ as the word separator.  So, when calling foo, we put a @ at any location at which we want word splitting.