2

Looking at the (prior) title, it has great chance to be marked as "duplicate".

I have a script (test.sh) that does not take any arguments. I call it in following two ways :

bash "test.sh"
# BASH_ARGC=()
# BASH_ARGV=()

bash -c "source test.sh"
# BASH_ARGC=([0]="1" [1]="0")
# BASH_ARGV=([0]="test.sh")
# BASH_EXECUTION_STRING='source test.sh'

The only differences I found are those three bash variables. As test.sh does not take any arguments, I presume those differences are irrelevant.

Are there any other differences ?

Put another way, what (in test.sh) can work in one calling method, but not in the other ?

Update 1

@JdeBP, @Stephen Kitt

Thank you for answering, but my point is not about detection of the differences, but about real differences that could affect an average programmer.

$0 being different is rarely "used" by an average programmer.

8
  • See superuser.com/questions/176783/… Jan 24, 2020 at 20:21
  • 1
    Sourced files run in the current shell and executed have their own. Any variables, functions, etc defined in your script will now be defined in your shell if you source it. Also if your script calls exit at all and you source it you will exit from your current shell session.
    – jesse_b
    Jan 24, 2020 at 20:23
  • 1
    @jesse_b but given how the script is invoked in both cases here ... Jan 24, 2020 at 20:24
  • It isn't a duplicate. This could do with a better title, because everyone is going to wrongly leap for the usual duplicate. The usual duplicate question is asking about a different scenario to this. Here, there's a child process non-interactive shell in both cases.
    – JdeBP
    Jan 24, 2020 at 20:44
  • The POSIX-conformant form of the question, probably best addressed as a separate Q&A, is of course whether a (conformant) script can detect the difference between sh somescript and sh -c '. somescript'.
    – JdeBP
    Jan 24, 2020 at 20:56

1 Answer 1

1
bash -c "source test.sh"

is a somewhat unusual way of running test.sh, combining source with a separate shell.

This can be detected by looking at $0; a typical form would be

if [ "${0##*/}" = "test.sh" ]; then
    # being run directly
else
    # being sourced
fi

since $0 won’t reflect the script when source is involved.

Apart from argument handling, there shouldn’t be any practical difference from test.sh’s perspective between

bash test.sh

and

bash -c "source test.sh"

however the latter form will prefer a test.sh on the PATH to a test.sh in the current directory.

See What is the difference between sourcing ('.' or 'source') and executing a file in bash? for details of the differences when sourcing a script in the current shell.

3
  • 1
    Try putting a different test.sh in a directory on your path. (-:
    – JdeBP
    Jan 24, 2020 at 21:29
  • Stephen, both forms just look at current directory to find the script, if I'm not mistaken.
    – Philippe
    Jan 24, 2020 at 22:12
  • 1
    @Philippe, no, see the documentation for .: “If filename does not contain a slash, the PATH variable is used to find filename. When Bash is not in POSIX mode, the current directory is searched if filename is not found in $PATH.” Jan 24, 2020 at 22:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.