Americas

  • United States
sandra_henrystocker
Unix Dweeb

Getting started with scripting on Linux, Part 1

How-To
Dec 11, 20236 mins
Linux

Once a script is prepared and tested, you can get a significant task completed simply by typing the script's name followed by any required arguments.

Letterpress, TypeScript
Credit: Jakub Krechowicz/Shutterstock

Developing scripts to handle your more complicated tasks can make your efforts on the Linux command line considerably easier and more reliable – at least once the scripts are written and tested. Scripts, after all, provide a way for you to turn a complicated series of commands into something you can invoke by typing only the name of the script. In this post, we’ll take a look at the syntax and commands that are used in bash scripts and provide some many examples and suggestions.

This post is intended to help new Linux users get comfortable with scripting and learn some ways to ensure their scripts are both reliable and easily maintained. This post also offers some suggestions on formatting scripts to improve readability.

The first line

The first line of a bash script is nearly always #!/bin/bash. This line ensures that the bash shell will be used to run the commands. Without this kind of start line, whatever shell you are currently using would inherit the job of running the commands in the script. Including #!/bin/bash as the first line ensures that the compatible shell is always used to run the commands.

The first two characters in that line (#!) are often referred to as “shebang” (pronounced shi-BANG). The rest of the line reflects the location of the bash shell. You can verify this on your system with a command like this:

$ ls -ld /bin/bash
-rwxr-xr-x. 1 root root 1439288 Nov  9 19:00 /bin/bash

The response shows the bash shell executable along with its size and permissions.

Adding comments

Comments are short descriptions that can be added to scripts to explain how various commands work and what they are supposed to be doing. These explanations can be especially helpful when scripts need to be updated as they make the more complex commands easier to understand. Comments are blocked from being evaluated by the shell as commands because they follow pound signs. Here’s are some examples:

# Collect information on the contractor’s location
loop=0	# start with loop count = 0

The first line above shows a comment on a line by itself. The second shows a comment following a command.

Note that while comments can be very useful in making scripts easier to understand, over-commenting is generally a bad idea. Use comments to explain what a group of commands is doing, but not every line.

Using arguments with scripts

Arguments are values that are provided to scripts when they are run. The person running a script will add them following the name of the script. For example:

$ myscript Monday 11AM

The script will refer to arguments like these as $1 and $2 etc. It might include commands such as this to work with them:

if [ $1 == "Sunday" ]; then		# don’t run on Sundays
    exit
fi

You can test the number of arguments provided to a script with a command like this:

if [ $# == 0 ]; then	# no arguments provided
    echo "please enter at least one argument"
    exit
fi

That $# represents the number of arguments provided by the person running the script. In the lines above, the script checks to see if no arguments were provided and exits if this is the case.

Collecting variables

Your scripts will be easier to read if you give the arguments names (i.e., assign the argument values to variables):

if [ $# == 2 ]; then
    month=$1
    year=$2
fi

If no arguments are provided when a script is run, you can still add a prompt asking for the data required as in this example:

if [ $# == 0 ]; then	# no arguments provided
    echo -n “Month: “
    read month
    echo -n “Year: “
    read year
    echo “Using: $month $year”
fi

Afterwards, you can use the more meaningful names to work with the variables. The code below will prompt for the arguments if they are not provided and ensure the variables with have the same names whether they are provided as arguments or in response to a prompt.

if [ $# == 2 ]; then
    month=$1
    year=$2
else
    echo -n “Month: “
    read month
    echo -n “Year: “
    read year
    echo “Using: $month $year”
fi

Usage statements

Another thing you can do when you need to collect information from whoever runs a script is to print a usage statement and exit if the arguments are not provided. Here’s an example:

#!/bin/bash

if [ $# == 0 ]; then
    echo "Usage: $0 month year"
    exit
fi

Given the usage statement, the script will remind the user of the required arguments and then exit so the person can run the script again, but with an understanding of what is expected.

Formatting for readability

As the examples shown in this post have shown, formatting (e.g., indenting lines) can make a difference in how readable a script will be. The commands to be run within the body of an if statement, for example, should be indented to make the extend of the if command obvious.

Permissions!

Don’t forget to make your scripts executable by using a chmod command like “chmod 755 myscript”.

Wrap-up

Preparing scripts to manage various tasks helps a lot. Once a script is prepared and tested, you will rarely have to make changes and can get a significant task completed simply by typing the script’s name followed by any required arguments.

Part 2 of this series will follow-up with many ways to test variables, looping through a series of variables and using case statements (a technique that allows you to associate commands with particular values.

sandra_henrystocker
Unix Dweeb

Sandra Henry-Stocker has been administering Unix systems for more than 30 years. She describes herself as "USL" (Unix as a second language) but remembers enough English to write books and buy groceries. She lives in the mountains in Virginia where, when not working with or writing about Unix, she's chasing the bears away from her bird feeders.

The opinions expressed in this blog are those of Sandra Henry-Stocker and do not necessarily represent those of IDG Communications, Inc., its parent, subsidiary or affiliated companies.