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.

4
  • What line in the output did you not expect?
    – choroba
    Jan 10, 2022 at 16:43
  • 1
    I don't understand your question. You're explicitly passing arguments "xx" and "yy" to the function, that's how $2 and $3 are populated. Then when you call "source" (.), you're providing them again. At a bash prompt, type help . Jan 10, 2022 at 16:45
  • @choroba I am confused that calling func_to_call_sub_scrp print.sh sends the text 'print.sh' as $1 to print.sh. the example with 2 arguments shows that it is not passed when actual arguments are supplied. I will edit the end to make it clear which function call is confusing
    – guest
    Jan 10, 2022 at 16:55
  • 3
    See also: When is double-quoting necessary? Jan 10, 2022 at 17:07

1 Answer 1

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?.

Not the answer you're looking for? Browse other questions tagged .