3

In bash, when you source a file with dot:

. /some/script

you can pass positional arguments to that script:

. /some/script hello world

and then access them in the script with $1, $2, ... etc as usual. However, if they are omitted the script gets the positional arguments of the enclosing script, that is, if you have:

#!/bin/sh
#--------------script1
. ./script3 hello world

#!/bin/sh
#--------------script2
. ./script3


#--------------script3
echo $1 $2

and then do:

./script1
./script2 bonjour monde

Your results are:

hello world
bonjour monde

So, is there any way as the author of script3 to tell if your positional arguments were passed explicitly to you (as script1 does) or just got copied from the outer script (as in the script2 example)?

[EDIT] Per the suggestion in the comments, I added printing of the values in the BASH_ARGV array so script3 is now:

echo ===========script3======
echo dollar-number args: 0=$0, 1=$1, 2=$2
for i in ${!BASH_ARGV[@]} ; do
        echo BASH_ARGV[$i]: ${BASH_ARGV[$i]}
done
echo ""

But the results are confusing:

./script1  
script1 calling script3 with args: hello world  
===========script3======  
dollar-number args: 0=./script1, 1=hello, 2=world  


./script2  
script2 calling script3 with no args:  
===========script3======  
dollar-number args: 0=./script2, 1=, 2=  
BASH_ARGV[0]: ./script3  


./script1 bonjour monde  
script1 calling script3 with args: hello world  
===========script3======  
dollar-number args: 0=./script1, 1=hello, 2=world  
BASH_ARGV[0]: monde  
BASH_ARGV[1]: bonjour  


./script2 bonjour monde  
script2 calling script3 with no args:  
===========script3======  
dollar-number args: 0=./script2, 1=bonjour, 2=monde  
BASH_ARGV[0]: ./script3  
BASH_ARGV[1]: monde  
BASH_ARGV[2]: bonjour

Why is BASH_ARGV[0] sometimes the script name and sometimes missing and sometimes the last argument? Also the arguments are in reverse order? What a mess.

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
John Hascall
  • 287
  • 1
  • 14
  • In bash specifically, explicit arguments show up in BASH_ARGV; you could compare that to `$@` – Jeff Schaller Jul 23 '19 at 16:33
  • What are you asking about? The positional parameters to a sourced script, or `BASH_ARGV`? Because they are not really one single thing – ilkkachu Jul 23 '19 at 17:49
  • My (original) question was how to tell if the args a sourced-script sees are really its args or ones in inherited from the enclosing script. The suggestion above indicated that BASH_ARGV might be a solution to my question (but it left me with only more questions). – John Hascall Jul 23 '19 at 19:11
  • From man bash: *referencing this variable* **ARGV** *when extdebug is not set, may result in inconsistent values* –  Aug 18 '19 at 22:06

0 Answers0