1

I have written a test script( let's call it test.sh) in bash. and the start of the script has following declaration:

#!/bin/bash -e

followed by some code.

Now it shows different results when i invoke it as bash test.sh versus ./test.sh. How is it possible. I thought by default ./test.sh reads the default shell from the first line of script and invokes it with that. Is my understanding correct.

3
  • 1
    It only does that if you don't invoke it with another command. Commented Feb 8, 2016 at 10:25
  • 2
    If you want the -e behaviour in your script regardless of how it was called, use set -e instead. Commented Feb 8, 2016 at 10:46
  • @choroba thanks, will do that :) Commented Feb 9, 2016 at 7:42

1 Answer 1

2

The #!/bin/bash -e shebang is only used when you (try to) execute a file (that isn’t a binary executable) as a command. This line informs the kernel which executable should be used to interpret the code in the script. See the shebang Wikipedia article for more information.

When you run ./test.sh, your current shell starts a new Bash sub-process with the -e option and this new process is the one that executes the commands in the script file.

When you run bash test.sh, you’re explicitly starting a new Bash sub-process (this time without the -e option) and it starts executing the commands in the file. When it encounters the shebang in the first line, it just treats it the same as any other comment beginning with #. (The shebang is also ignored as just another comment if you source the file using . test.sh).

To ensure that the Bash shell behaves a certain way, it’s best to use the set builtin instead of providing an option when invoking Bash. E.g., to ensure the shell exits when a command returns a non-zero status, you should include set -e at or near the start of the script.


For more in-depth information about how commands are executed with a Linux kernel, see this answer to What is the difference between running “bash script.sh” and “./script.sh” and the execve man page.

Sign up to request clarification or add additional context in comments.

4 Comments

Also note differences between using bash test.sh and sourcing the file (when you source the file, an exit will throw you out of the calling shell, when bash test.sh is finished changes in working dir and variables are lost).
@WalterA I've been there. It's particularly annoying if you're debugging and also set -u but the script exits early (before the set +u and set +e commands). That stopped me using source or . when developing/debugging shell scripts. :)
@AnthonyGeoghegan thanks for clearly explaining the behavior. but my question is still unanswered as to why would i get a incorrect result when executing the script like ./test.sh and i get the correct result if i run it bash test.sh way?
Hi @AnkitKumar I answered the two questions, How is it possible? and Is my understanding correct? to the best of my possibilities given the (general) information provided. If you want help debugging a related problem specific to your script, it would be better to create a How to create a Minimal, Complete, and Verifiable example and use it as the basis for a new, more specific (non-general) question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.