Scripts

shebang

A script is a file or program that contains a set of instructions that are interpreted and executed by another program, or interpreter. Python, R, and bash are all interpreted languages, and as such, can be used to create scripts.

Scripts are typically run by typing the name of the script in a terminal window, and then pressing the enter key. For example, let’s say we have an executable bash script named my_script.sh. To run this script in a shell, we would simply type the following, followed by enter.

/path/to/my_script.sh

If my_script.sh is in your current working directory, you cannot run it as follows.

my_script.sh

By default, the operating system will look in your $PATH for a runnable file to execute. If your current working directory is not in your $PATH, you will get an error message saying something like "command not found".

To run an executable file in the current working directory, prepend ./ to the file name. This specifies "in this directory".

./my_script.sh

Sometimes, you may get an error message saying something like "permission denied". Any file that you want to run must be executable. To make a file executable, you can use the chmod command.

chmod +x my_script.sh

A critical part to any script is the shebang, bang, or hash-bang. The shebang is used to indicate which interpreter should be used to execute the script. By default, the shell used to run the script will depend on the shell you are using. In zsh, scripts are executed using /bin/sh. In bash, scripts are executed using /bin/bash. For example, if you try to run the following Python script, you will get an error.

def main():
    print("Hello, world!")

if __name__ == '__main__':
    main()
./test.py: line 1: syntax error near unexpected token
./test.py: line 1: def main()

This error is a result of the shell for bash or zsh trying to use a non-python interpreter to interpret and run a Python script. One way to fix this is to specify the script as an argument to the Python interpreter you’d like to use.

python3 test.py
Hello, world!

Other types of scripts can do this as well.

/bin/bash test.sh
/bin/zsh test.sh
/bin/sh test.sh

The better way to fix this is to use a shebang. For example, if we were to modify our Python script to use a shebang, we could run it as follows.

#!/usr/bin/python3

def main():
    print("Hello, world!")

if __name__ == '__main__':
    main()
./my_script.py
Hello, world!

Although we used the shebang #!/usr/bin/python3 here, a more robust way to do this is use the following shebang instead: \#!/usr/bin/env python3. This tells the shell to use the python3 interpreter in your environment’s $PATH rather than the system’s python3 interpreter. This is particularly useful if you rarely use the system’s python3 and use virtual environments instead.

Similarly, for other types of scripts.

#!/bin/bash

echo "Hello, world!"
#!/bin/zsh

echo "Hello, world!"

The shebang line always goes on the first line of a script, by itself. The shebang starts with a hashtag followed immediately by an exclamation point (#!), which is then followed immediately by the absolute path to the interpreter that should be used to run the script.


Arguments

A bash script will start with the shebang on the first line, followed by a series of calls to the various UNIX tools and utilities.

#!/bin/bash

echo "Hello, world!"

Similarly to how utilities like cat or awk can accept arguments, bash scripts can accept arguments too. Let’s say we wanted to expand our script to accept a name as an argument.

./my_script.sh Alice
Hello, Alice!

To do this, we can use the following code.

#!/bin/bash

echo "Hello, $1!"
./my_script.sh Alice
Hello, Alice!

As you can see in the example above, $1 was replaced with the content of the first argument. In general, $1 holds the content of the first argument, $2 holds the content of the second argument, and so on.

$0 is a special variable that holds the name of the script, or path to the script.

my_script.sh
#!/bin/bash

echo "My script name: $0"
./my_script.sh
My script name: ./my_script.sh

Flags


Loops


Functions


Examples


Resources

A great overview of the popular ways to include arguments and options in bash scripts.