Same script opened in three different ways produces three different results. Why? [duplicate]

I have a sample script (credit goes to kos):

#!/bin/bash
cat <(cat /etc/lsb-release)

I save this script as somename.sh in my home directory.

Now, I try to open this file in three different ways:

sh somename.sh

bash somename.sh

./somename.sh

So, I have two questions:

  1. Why are the outputs for the above commands different though they are running the same script?

    • sh produces a Syntax error

    • bash outputs the desired result

    • ./ gives a Permission Denied error

  2. Why is it necessary to give the script executable permission only when running the script using ./ and not necessary in the other cases?

Thanks in advance!

EDIT: The first part might be similar to the duplicate linked one but, I did have a second question too.


As we discussed in the chat:

  1. sh script produces an error because calling the interpreter directly (in this case sh) ignores the shebang, and the script is run in sh; sh doesn't support process substitutions (<([...])), which are Bash-isms, so the script exits on error.

    bash script doesn't produce an error because despite the shebang being ignored the script is still run in Bash, which supports process substitutions.

    ./script produces an error because script is not executable.

  2. To run a script with ./ you must have the execute bit for your user set on the script, that's an OS' constraint.

    So the question actually is: why doesn't bash script require having the execute bit set for your user on script?

    That's because when running bash script the script is read by Bash, and Bash has the execute bit set for your user.

    That means that Bash, having the permission to execute code, can "bypass" the OS' constraint on that script, and all the script needs is to be readable by Bash.


  • sh is symlink to dash shell and produces a Syntax error because there is no <( . . .) in sh syntax. It's only in bash (and in zsh and ksh if I remember correctly ).

  • bash outputs the desired result because it's in right bash syntax, nothing wrong there

  • ./ gives a Permission Denied error because you basically say "Hey, shell, look at the permissions of that file and look at the first line (the one with #!/bin/bash ) in my current directory and figure out how to run this script for me". (side note: if you had the script in a location that is included into your $PATH variable, then you would just run myScriptName.sh and that's it, but the idea would be same, we need to check exec permissions and what interpreter to use)

Before you were running bash and dash and telling them to read commands from file. bash and dash are executable this time, not the script. Script now is source of commands, a parameter. Read permissions there are always set for all users, so shells will read it.