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:
-
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
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:
-
sh script
produces an error because calling the interpreter directly (in this casesh
) ignores the shebang, and the script is run insh
;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 becausescript
is not executable. -
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 onscript
?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 todash
shell and produces a Syntax error because there is no<( . . .)
insh
syntax. It's only in bash (and inzsh
andksh
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 runmyScriptName.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.