I create a bash script in the user directory that, when executed, for example, displays the text "Hello world". At the same time, I want to be able to execute it only myself (the owner of the file) and the accounts from my group, and all the rest could just read. Accordingly, I set the rights through chmod, I log in as a user not from my group, go to the directory with the file, run it through sh and ... it suddenly executes and displays "Hello world" instead of "Access denied". But how is this possible, I forbade others to perform? What it is? What does it mean?

[user@localhost ~]$ ls -la *.sh
-rwxr-xr-- 1 user users 0 Feb 19 01:21 file.sh
[user@localhost ~]$ sh file.sh
Hello World
[user@localhost ~]$ groups
users wheel
[user@localhost ~]$ su - testu
[testu@localhost ~]$ groups
[testu@localhost ~]$ cd ../user
[testu@localhost user]$ sh file1.txt
Hello World```
  • 7
    They can read the script, and by using sh they pass the script's contents as an argument into sh which they absolutely CAN execute. Also, where did you change the sh extension to txt? – QuickishFM Feb 22 '20 at 15:03
  • @QuickishFM, thanks, it make sense. But why then do we need the eXecution rights?So they do nothing? As for txt, this is a typo, although, as far as I know, it can also be executed. – MadEvil Feb 22 '20 at 15:22
  • 1
    the txt can be passed to sh, yes, but i only pointed it out as its inconsistent with the previous filename. Execution rights are used mostly by binary files which aren't read into a shell interpreter like sh, bash, etc, but are bytes directly decoded by the CPU. sh itself is the binary but it acts as the interpreter. If you make a hello world program in C, and compile, its not interpreted by sh any more, its executed by the CPU to give you the output - in this case, execution rules apply. – QuickishFM Feb 22 '20 at 15:33
  • 2
    Note: "Hello, World." should have a comma. If you don't believe me then consider the similar sentence "Let's eat children." vs "Let's eat, children." – ctrl-alt-delor Feb 22 '20 at 16:54
  • 1
    @QuickishFM It's also worth noting that, even in the case of native/binary code, having read permission on a file implies that the user will be able to execute it by making their own copy of the file and executing the copy. The only times when denying execute permission (but allowing read permission) has any real value are when the file is setuid and will execute under the owner's user account regardless of who's actually executing it or when the code's behavior depends on the location/path of the executable file and you don't want certain users to be able to execute it in that location. – Micheal Johnson Feb 23 '20 at 14:41

There are different ways to "execute" a script, that have subtle differences:

  • run sh /path/to/script: The script needs no execute permissions! In fact you execute sh, which in turn reads and interprets the script. So the moment you may read it, you can not execute it, but tell the shell to read it and act upon it which is nearly the same thing as executing it.
  • directly run /path/to/script after adding a #!/bin/sh header and giving execution privileges. In this case you execute the script itself, with the shebang header telling which shell to load
  • run . /path/to/script: This tells your current shell to load the script and interpret it as if you were inputing its content into the shell prompt. Again no execution privileges are needed, as you don't execute the file, but read it.

You can make the differences visible with a script, that says just echo "$0". In the first case it will output the path to sh, in the second case the path to the script and in the third case the path to your current shell.

  • 1
    The last paragraph seems to be wrong, at least with my /bin/sh. For a script consisting of echo "$0" + shebang, I always ./foo.sh, no matter if I use sh ./foo.sh or ./foo.sh. – Jonas Schäfer Feb 23 '20 at 16:44
  • @JonasSchäfer Adding a shebang is where you deviated from Eugen's story. – Asteroids With Wings Feb 23 '20 at 18:32
  • @AsteroidsWithWings I don’t see a difference with or without shebang. I just added it to be sure that it’s executed with /bin/sh instead of /bin/bash. – Jonas Schäfer Feb 25 '20 at 15:35
  • @JonasSchäfer Oh :P – Asteroids With Wings Feb 25 '20 at 18:01

Because you are not executing it you are reading it, into the sh interpreter (sh does not check the execute bit).

If you add #!/bin/sh as the first line. Then it can be executed e.g. ./file-name

Also even if the sh ./file-name option was not available (as it is with non interpreted programs (e.g. C, C++, pascal, go), then a user that can read it, could make a copy and set the execute bit on their copy (If you can read it, then you can run it).

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.