0

I have a script print.sh:

#!/bin/bash
echo printing provided args:

for i in "$@"; do echo -e "\t${i}" done

If I do this at the prompt a=$(. print.sh ); echo "${a}" then I get printing provided args: as the stored output

My main script to test command substitution looks like this:

#!/bin/bash
function func_to_call_sub_scrp
        {
        # Call  sub-script
        capture="$(. $1  $2 $3)"
        echo -e "captured output:
\t\t${capture}"
        }

echo "Run function to call sub script without parameters passed. " func_to_call_sub_scrp print.sh echo "" echo "Run function to call sub script with parameters passed." func_to_call_sub_scrp print.sh xx yy

This outputs:

Run function to call sub script without parameters passed. 
captured output:
                printing provided args:
        print.sh

Run function to call sub script with parameters passed. captured output: printing provided args: xx yy

The second call sends xx and yy to print.sh which is as expected. However when I send "print.sh" "" "" command substitution calls print.sh and sends it print.sh as its $1 instead of sending it "" and ""

My question is how is $1 being passed as an argument to the printing script when there are no other inputs? I expected "$(. $1 $2 $3)" to become "$(. print.sh )" or "printing provided args:" once returned.

guest
  • 77

1 Answers1

0

Note that you do not run . "print.sh" "" "" in the first example. You are running . print.sh since you are not quoting $2 or $3.

From the bash manual, regarding source (and .), with my emphasis:

[...] If any arguments are supplied, they become the positional parameters when filename is executed. Otherwise the positional parameters are unchanged.

When you call . print.sh, you do not provide arguments to the dot-script print.sh, and the positional parameters are therefore unchanged. But what are they?

The positional parameters in the dot-script will in the first call be the positional parameters of your function, which is the list consisting of the single string print.sh. This is why "$@" expands to print.sh inside the dot-script.


Just comments:

A better way to output all positional parameters with a tab indent:

printf '\t%s\n' "$@"

This avoids issues with echo described elsewhere. A similar comment could be made about the way you output $capture in the function.

You also need to quote the expansion of $1, $2, and $3, unless you want the shell to split them on the characters in $IFS and apply filename globbing on the resulting words. See When is double-quoting necessary?.

Kusalananda
  • 333,661