I know it, forget it and relearn it again. Time to write it down.
7 Answers
To run a non-executable sh
script, use:
sh myscript
To run a non-executable bash
script, use:
bash myscript
To start an executable (which is any file with executable permission); you just specify it by its path:
/foo/bar
/bin/bar
./bar
To make a script executable, give it the necessary permission:
chmod +x bar
./bar
When a file is executable, the kernel is responsible for figuring out how to execte it. For non-binaries, this is done by looking at the first line of the file. It should contain a hashbang
:
#! /usr/bin/env bash
The hashbang tells the kernel what program to run (in this case the command /usr/bin/env
is ran with the argument bash
). Then, the script is passed to the program (as second argument) along with all the arguments you gave the script as subsequent arguments.
That means every script that is executable should have a hashbang. If it doesn't, you're not telling the kernel what it is, and therefore the kernel doesn't know what program to use to interprete it. It could be bash
, perl
, python
, sh
, or something else. (In reality, the kernel will often use the user's default shell to interprete the file, which is very dangerous because it might not be the right interpreter at all or it might be able to parse some of it but with subtle behavioural differences such as is the case between sh
and bash
).
A note on /usr/bin/env
Most commonly, you'll see hash bangs like so:
#!/bin/bash
The result is that the kernel will run the program /bin/bash
to interpret the script. Unfortunately, bash
is not always shipped by default, and it is not always available in /bin
. While on Linux machines it usually is, there are a range of other POSIX machines where bash
ships in various locations, such as /usr/xpg/bin/bash
or /usr/local/bin/bash
.
To write a portable bash script, we can therefore not rely on hard-coding the location of the bash
program. POSIX already has a mechanism for dealing with that: PATH
. The idea is that you install your programs in one of the directories that are in PATH
and the system should be able to find your program when you want to run it by name.
Sadly, you cannot just do this:
#!bash
The kernel won't (some might) do a PATH
search for you. There is a program that can do a PATH
search for you, though, it's called env
. Luckily, nearly all systems have an env
program installed in /usr/bin
. So we start env
using a hardcoded path, which then does a PATH
search for bash
and runs it so that it can interpret your script:
#!/usr/bin/env bash
This approach has one downside: According to POSIX, the hashbang can have one argument. In this case, we use bash
as the argument to the env
program. That means we have no space left to pass arguments to bash
. So there's no way to convert something like #!/bin/bash -exu
to this scheme. You'll have to put set -exu
after the hashbang instead.
This approach also has another advantage: Some systems may ship with a /bin/bash
, but the user may not like it, may find it's buggy or outdated, and may have installed his own bash
somewhere else. This is often the case on OS X (Macs) where Apple ships an outdated /bin/bash
and users install an up-to-date /usr/local/bin/bash
using something like Homebrew. When you use the env
approach which does a PATH
search, you take the user's preference into account and use his preferred bash over the one his system shipped with.

- 120,288
- 16
- 68
- 77
-
77Thank you for taking the time to write a good answer to a simple question. – P-A Apr 27 '09 at 13:32
-
6If I use `zsh` as my shell, would I use the `hashbang` `#! /usr/bin/env zsh`? – stefmikhail May 15 '12 at 15:15
-
6@stefmikhail: It doesn't matter which shell interpreter you use to *invoke* the script, you should use `#! /usr/bin/env zsh` if (and only if) the code *inside* the script should be executed by the Z shell. – johnsyweb Aug 31 '13 at 03:29
-
1+1 for explanation. i tend to forget but knowing the meaning of the command will help me to recollect. – Angelin Nadar Feb 03 '14 at 14:21
-
One small caveat is that a hash bang will usually *not* work when you save a file with DOS (`\r\n`) line endings (Not on Linux & BSD, anyway). You *need* to use UNIX-style line endings (`\n`). – Martin Tournoij Apr 25 '14 at 06:52
-
2@Carpetsmoker This is correct, and not limited to the hashbang. bash scripts should always use UNIX line endings otherwise the last argument of every command will have a \r appended to it, just like the hashbang command name will. – lhunath Apr 26 '14 at 13:47
-
@lhunath Why is that an issue? – voices Jul 07 '16 at 16:44
-
1@tjt263 Why is it an issue to append \r to the last argument of every command? Because now `rm foo` won't delete `foo`, it will delete `foo\r`. Every command that is not `echo` will be broken. – lhunath Jul 08 '16 at 17:00
-
env could bite you if you're trying to run the script form cron. – Jasen Jan 11 '17 at 12:04
-
The goal of portability is admirable, but unfortunately (and partly as a result of this post) we now see `#!/usr/bin/env` parrotted in many places where it should NOT be used. For example, for POSIX shell scripts `#!/bin/sh` is no less portable than `#!/usr/bin/env sh`. Failing to sanitize PATH before relying on it is a strike against security, and so using env should only be done where the file MUST be run unmodified on an unknown OS. In other circumstances the path to the interpreter should be resolved either during package construction, or as part of the process of installing the script. – Martin Kealey Feb 16 '22 at 22:06
To start the shell-script 'file.sh':
sh file.sh
bash file.sh
Another option is set executable permission using chmod command:
chmod +x file.sh
Now run .sh file as follows:
./file.sh

- 109,922
- 25
- 130
- 137

- 10,882
- 8
- 26
- 19
For the bourne shell:
sh myscript.sh
For bash:
bash myscript.sh
-
Thank you for answering this quite obvious question. For a Mac guy like me it is easy to forget the old Unix commands between the laps. – P-A Apr 09 '09 at 11:45
If you want the script to run in the current shell (e.g. you want it to be able to affect your directory or environment) you should say:
. /path/to/script.sh
or
source /path/to/script.sh
Note that /path/to/script.sh
can be relative, for instance . bin/script.sh
runs the script.sh
in the bin
directory under the current directory.

- 64,182
- 22
- 135
- 226
-
7Be **very** careful when sourcing or dot'ing with relateive pathnames. You should **always** start them with ./ If you don't do this, and the relative pathname doesn't contain any slashes, you'll be sourcing something in PATH, BEFORE something in the current directory! Very dangerous for abuse. – lhunath Apr 09 '09 at 12:49
First, give permission for execution:-
chmod +x script_name
- If script is not executable:-
For running sh script file:-
sh script_name
For running bash script file:-
bash script_name
- If script is executable:-
./script_name
NOTE:-you can check if the file is executable or not by using 'ls -a'

- 1,515
- 4
- 21
- 31
The file extension .command is assigned to Terminal.app. Double-clicking on any .command file will execute it.

- 1,440
- 17
- 35
Little addition, to run an interpreter from the same folder, still using #!hashbang in scripts.
As example a php7.2 executable copied from /usr/bin is in a folder along a hello script.
#!./php7.2
<?php
echo "Hello!";
To run it:
./hello
Which behave just as equal as:
./php7.2 hello
The proper solutions with good documentation can be the tools linuxdeploy and/or appimage, this is using this method under the hood.

- 11,480
- 1
- 88
- 87