How can I run a shell script on a Unix console or Mac terminal?
I know it, forget it and relearn it again. It is time to write it down.
To run a non-executable Bourne shell (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 execute 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 interpret it. It could be Bash, the Perl interpreter, the Python interpreter, Bourne shell, or something else. (In reality, the kernel will often use the user's default shell to interpret 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 Bourne shell and Bash).
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, executable 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 hard coded path, which then does a PATH search for executable 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 don’t have any space left to pass arguments to bash. So there isn’t any 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 file, but the user may not like it, may find it's buggy or outdated, and may have installed his/her own bash executable somewhere else. This is often the case on OS X (Macs) where Apple ships an outdated /bin/bash file and users install an up-to-date /usr/local/bin/bash file 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/her preferred Bash over the one his/her system shipped with.
zsh as my shell, would I use the hashbang #! /usr/bin/env zsh?#! /usr/bin/env zsh if (and only if) the code inside the script should be executed by the Z shell.To start the shell script 'file.sh':
sh file.sh
bash file.sh
Another option is set executable permissions using the chmod command:
chmod +x file.sh
Now run the .sh file as follows:
./file.sh
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.
First, give permissions for execution:
chmod +x script_name
If the script is not executable:
For running a Bourne shell (executable sh) script file:
sh script_name
For running a Bash script file:
bash script_name
If the script is executable:
./script_name
Note: You can check if the file is executable or not by using 'ls -a'