Can scripts run even when they are not set as executable?

I can seem to run scripts (.sh) with and without them being set as executable. So where exactly this matters?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

Let’s say you have the file myscript containing the following:

#!/bin/bash
echo "Hello, World!"

If you make this file executable and run it with ./myscript, then the kernel will see that the first two bytes are #!, which means it’s a script-file. The kernel will then use the rest of the line as the interpreter, and pass the file as its first argument. So, it runs:

/bin/bash myscript

and bash reads the file and executes the commands it contains.

Thus, for bash (or whatever interpreter your script requires) to “execute” the script, it only needs to be able to read the file.

So, for scripts, the execute bit just makes it a bit more convenient to execute it. As long as bash is executable, you can always run bash with the script file as argument, or run bash interactively and copy paste the script line by line into your terminal to have the commands executed.

Solution 2

Make sure you are not confusing “executing the shell script” with “run a shell script using sh”.

This will not be affected by file permissions on file.sh:

sh file.sh

You are executing sh (which resolves to the program /bin/sh), which reads file.sh and executes it’s code.

File permissions will have effect if you really execute the script itself :

./file.sh

Note that file permissions are not supported by non-Linux filesystems, like FAT. So even if you run chmod -x file.sh, the file will still have it’s former permissions.

Execute permission is enforced by the filesystem. But programs can “execute” the code too by reading the file contents, which bypasses filesystem permissions on “execute”.

Solution 3

The exec syscall of the Linux kernel fails with EACCES if the file is not executable

While you can do sh myprog.sh (which just reads the files and interprets is), trying to run the program as ./myprog.sh cannot work, since when you do that:

This can be verified with main.c:

#define _XOPEN_SOURCE 700
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int main(void) {
    char *argv[] = {"myprog", NULL};
    char *envp[] = {NULL};
    int ret;
    ret = execve("myprog.sh", argv, envp);
    perror("execve");
    printf("%d\n", errno);
    printf("%d\n", EACCES);
}

and myprog.sh:

#!/bin/sh
echo worked

If myprog.sh is not executable, main fails with:

execve: Permission denied
13
13

Tested in Ubuntu 17.10, gcc -std=c99.

POSIX 7 mentions that at:

The exec functions, except for fexecve(), shall fail if:

[EACCES] Search permission is denied for a directory listed in the new process image file’s path prefix, or the new process image file denies execution permission.

Further rationale can be found at: https://security.stackexchange.com/questions/66550/unix-execute-permission-can-be-easily-bypassed-is-it-superfluous-or-whats-the

Solution 4

Don’t think of it in the way that. Can I execute this file? Think of it in the way that: Who can execute this file?

If the computer is yours and the file is yours I am sure you can execute it. You might want to look further into commands like chmod and chown, and file permissions.

I hope that helps.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply