Bash Script without #!/

GoodBetterBest

Supremacy Member
Joined
Jan 23, 2019
Messages
6,239
Reaction score
2,119
Linux scripts starts with #!/
I'm preparing a script to run on another system which may have a different location or shell.
I can omit this #!/ so that I don't get permission error on that system.

I'm can't find online what is the impact if I don't have #!/.

Any advice is appreciated.

Thanks !
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,301
Linux scripts starts with #!/
I'm preparing a script to run on another system which may have a different location or shell.
I can omit this #!/ so that I don't get permission error on that system.

I'm can't find online what is the impact if I don't have #!/.

Any advice is appreciated.

Thanks !
It's called shebang and it's only the 2 characters #! without the slash(/). What comes after the shebang is the interpreter file path, and it doesn't have to be absolute file path.

Bash:
$ ls -al | grep mycat
lrwxr-xr-x     1 davidktw  staff           8 Dec 21 13:28 mycat -> /bin/cat

$ cat ./meow.sh
#!./mycat -n

Meow!!!

$ ./meow.sh
     1    #!./mycat -n
     2
     3    Meow!!!

You can always execute the script with another interpreter and it will override the shebang.
As you can see above, when I start the meow.sh, I uses ./mycat -n which is the same as /bin/cat -n, which display the line numbers.
Below you will see if I invoke the script directly without the -n option of the cat utility, there will be no line numbers printed

Bash:
$ /bin/cat meow.sh
#!./mycat -n

Meow!!!

Most unix utilities knows how to ignore the shebang when it is encountered at the first line of the script because it is a well-known mechnism
https://en.wikipedia.org/wiki/Shebang_(Unix)
If you don't have the interpreter provided via the shebang, then when executing the input file (normally text), you will need to explicitly provide the interpreter as such, unless it is a shell script, because the shell will knows how to react to the commands.

Bash:
$ cat ./meow.sh
Meow!!!
$ ./meow.sh
./meow.sh: line 1: Meow!!!: command not found
$ cat meow.sh
Meow!!!
 
Last edited:

GoodBetterBest

Supremacy Member
Joined
Jan 23, 2019
Messages
6,239
Reaction score
2,119
Hi David

The reason I ask is that when I put the wrong shebang, it complained:

-bash: ./test.sh: /usr/bash: bad interpreter: No such file or directory

The correct path is: #!/usr/bin/bash

So I thought if I were to give it to somebody to run and the person interpreter is not in the same location, then script will fail.

So I thought if I don't need to put in the shebang, I just omit it but I don't know what would be the repurcussion.
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,301
Hi David

The reason I ask is that when I put the wrong shebang, it complained:

-bash: ./test.sh: /usr/bash: bad interpreter: No such file or directory

The correct path is: #!/usr/bin/bash

So I thought if I were to give it to somebody to run and the person interpreter is not in the same location, then script will fail.

So I thought if I don't need to put in the shebang, I just omit it but I don't know what would be the repurcussion.
Generally shells are quite hardly. If you specify a command, the shell will attempt to execute the script and make some good deduction based on some intrinsic rules of what it is and execute it as a script in most cases. That being said, in the case where there may be multiple shell implementations in your system, it can be tricky which should be used, most likely the first one in the PATH environment variable

In your case, what you want to do is the following. Use the following shebang instead of hardcoding the path of the bash if that is the shell you would like the script to be interpreted

Bash:
#!/usr/bin/env bash

What the above does is populate the environment variables of the parent process that is executing the /usr/bin/env command into the child process and then execute the bash. This way, if there is a bash somehow in the PATH environment, it will be picked up and executed as the interpreter to interpret this script.

I do this for a lot of my shell and perl scripts and other utilities too

Bash:
#!/usr/bin/env perl
#!/usr/bin/env bash

Read this.
https://www.cyberciti.biz/tips/finding-bash-perl-python-portably-using-env.html
Apparently /usr/bin/env is quite consistently placed across most(if not all) unices.
If you are dealing with just Linux, we are not even really discussing about cross-platforms because when I refer to unices, it is cross platforms between BSD, Solaris, HP-UX, IBM AIX, Mac OS X, etc.

Someone whom is adequately experienced working in unices should knows about how executables are searched with PATH env var and should knows how to deal with a missing or faulty interpreter path.

:)
 
Last edited:

GoodBetterBest

Supremacy Member
Joined
Jan 23, 2019
Messages
6,239
Reaction score
2,119
Generally shells are quite hardly. If you specify a command, the shell will attempt to execute the script and make some good deduction based on some intrinsic rules of what it is and execute it as a script in most cases. That being said, in the case where there may be multiple shell implementations in your system, it can be tricky which should be used, most likely the first one in the PATH environment variable

In your case, what you want to do is the following. Use the following shebang instead of hardcoding the path of the bash if that is the shell you would like the script to be interpreted

Bash:
#!/usr/bin/env bash

What the above does is populate the environment variables of the parent process that is executing the /usr/bin/env command into the child process and then execute the bash. This way, if there is a bash somehow in the PATH environment, it will be picked up and executed as the interpreter to interpret this script.

I do this for a lot of my shell and perl scripts and other utilities too

Bash:
#!/usr/bin/env perl
#!/usr/bin/env bash

Read this.
https://www.cyberciti.biz/tips/finding-bash-perl-python-portably-using-env.html
Apparently /usr/bin/env is quite consistently placed across most(if not all) unices.
If you are dealing with just Linux, we are not even really discussing about cross-platforms because when I refer to unices, it is cross platforms between BSD, Solaris, HP-UX, IBM AIX, Mac OS X, etc.

Someone whom is adequately experienced working in unices should knows about how executables are searched with PATH env var and should knows how to deal with a missing or faulty interpreter path.

:)

Thanks again. I'll code #!/usr/bin/env bash from now on just to be sure. :)
 
Important Forum Advisory Note
This forum is moderated by volunteer moderators who will react only to members' feedback on posts. Moderators are not employees or representatives of HWZ Forums. Forum members and moderators are responsible for their own posts. Please refer to our Community Guidelines and Standards and Terms and Conditions for more information.
Top