- Track US election results on your iPhone, iPad or Apple Watch - here's how
- How to Become a Chief Information Officer: CIO Cheat Sheet
- 3 handy upgrades in MacOS 15.1 - especially if AI isn't your thing (like me)
- Your Android device is vulnerable to attack and Google's fix is imminent
- Microsoft's Copilot AI is coming to your Office apps - whether you like it or not
Basic scripting on Unix and Linux
Creating a script on a Unix or Linux system can be dead easy or surprisingly complex; it all depends on how much you’re trying to get the script to do. In this post, we look at scripting basics—at how to get started if you have never built a script before.
Identifying the shell
Unix and Linux systems today have a number of shells that you can use. Each shell is a command interpreter. It reads commands and sends them to the kernel for processing.
Bash is one of the most popular, but there’s also zsh, csh, tcsh and korn. There’s even one called fish that can be especially nice for Linux beginners because of its helpful command auto-completion options. To determine which shell you are using, use this command:
$ echo $SHELL /bin/bash
You can also determine your primary shell by checking the /etc/passwd file:
$ grep $USER /etc/passwd nemo:x:1111:1111:Nemo the Fish:/home/nemo:/bin/bash <== /bin/bash
One way to determine what shells are available on a Linux system is to check the /etc/shells file.
$ more /etc/shells # /etc/shells: valid login shells /bin/sh /bin/dash /bin/bash /bin/rbash /bin/zsh /usr/bin/zsh /usr/bin/screen /usr/bin/tmux /usr/bin/fish
The system shown above claims to have nine available shells.
Which shell is best for any indifidual depends largely on what they’re used to using since much of the syntax in scripting does not represent the commands that you will find in /bin, /usr/bin or /usr/local/bin. Instead, they are part of the shell itself and are called “built-ins”. This includes the commands used for looping (e.g., for and while).
One easy choice for scripting is to use whatever shell you use on the command line since, after all, you’ll be more or less comfortable using it.
Selecting your shell
To determine which of the available shells will run the commands in your script, make the first line of your script look like one of these:
#!/bin/sh #!/bin/dash #!/bin/bash #!/bin/rbash #!/bin/zsh #!/usr/bin/zsh #!/usr/bin/screen #!/usr/bin/tmux #!/usr/bin/fish
When the first line of your script identifies the shell to be used, that shell will run the commands in the script. If you do not include the shell as the first line in a script, the shell you use when you invoke the script will be the one that runs it.
Running a command
Any command you run on the Linux command line can be run in a script provided it’s compatible with the specified shell. Use your favorite text editor and type in your commands. Here’s a very simple script that shows the current date in a day-month-year format. I call this script “today”.
#!/bin/bash date +”%d %B %Y”
To run it …
$ today 08 March 2021
Adding a comment
It’s a good idea to add comments to scripts that explain what a script is meant to accomplish—especially when a script is long or the syntax is complicated. Just start the comment with a # sign. Comments can be lines by themselves or added to the end of commands in the script. For example:
#!/bin/bash # display the date/time repeatedly in a loop while true do echo -n “still running ...” date sleep 300 # sleep 5 minutes done
Making the file executable
To make a script executable, use the chmod command and make sure that the intended users can run it. For example:
$ chmod 700 myscript # you can run it $ chmod 755 myscript # everyone can run it
If a script isn’t set up to be executable, it can still be run using the “.” built-in that “sources” (i.e., reads and runs) the script.
$ . today 08 March 2021
Using an if command
The if command allows you to test conditions or variables. In this example, we check to see if the script is being run on a Friday.
if [ `date +”%A”` == Friday ];then echo “TGIF!”; fi
The basic syntax for an if command is “if value == other_value”. The == performs a comparison, and it’s necessary to ensure that the shell sees one value on each side of the comparison operator. For this reason, you often have to put your strings in quotes of some kind.
Understanding variables
Just to be sure this is clear, it’s important to understand that variables are assigned in one way and referenced in another. Assign a variable with just its name, but precede the name with a $ to use it.
$ favnum=11 $ echo $favnum 11
Prompting the user for input
To prompt a user within a script to enter some information, you need to provide both the prompt and the command to read what the user types. You should also assign a variable name that makes sense as in this example. Note that using the echo -n command means the user will enter their response on the same line as the prompt is displayed.
echo -n “How many loops?> “ read numloops
The person running the script will see the prompt and provide their response:
How many loops?> 11
Using command line arguments
To make use of arguments that a user enters along with the script name, you need to know how to identify them. Script arguments will be assigned the names $1, $2 and so on. For any argument that you’re going to use repeatedly, you might consider assigning those values to more meaningful variable names.
$!/bin/bash if [[ $1 != [0-9]* ]]; then echo “Error: $1 is not numeric” exit
else
loops=$1 fi
In this case, we’re checking to be sure that the first argument provided is numeric and exiting the script if it is not. If the response is numeric, we then assign it to the variable $loops to use later in the script.
Another useful thing to do in a script is to first verify that there are arguments. Otherwise syntax like what is shown above would fail because the shell would see “if [[ != [0-9]* ]];” which would generate a syntactical error.
To check that the number of arguments provided is correct, you could use syntax like the following that checks to be sure at least two arguments have been provided and, otherwise, reminds the user that both a number of lines and file name are required:
#!/bin/bash if [ $# -lt 2 ]; then echo “Usage: $0 lines filename” exit 1 fi
Different ways to loop
There are a number of ways to loop within a script. Use for when you want to loop a preset number of times. For example:
#!/bin/bash for day in Sun Mon Tue Wed Thu Fri Sat do echo $day done
or …
#!/bin/bashfor letter in {a..z} do echo $letter done
Use while when you want to loop as long as some condition exists or doesn’t exist.
#!/bin/bash n=1 while [ $n -le 4 ] do echo $n ((n++)) done
Using case statements
Case statements allow your scripts to react differently depending on what values are being examined. In the script below, we use different commands to extract the contents of the file provided as an argument by identifying the file type.
#!/bin/bash if [ $# -eq 0 ]; then echo -n “filename> “ read filename else filename=$1 fi if [ ! -f “$filename” ]; then echo “No such file: $filename” exit fi case $filename in *.tar) tar xf $filename;; *.tar.bz2) tar xjf $filename;; *.tbz) tar xjf $filename;; *.tbz2) tar xjf $filename;; *.tgz) tar xzf $filename;; *.tar.gz) tar xzf $filename;; *.gz) gunzip $filename;; *.bz2) bunzip2 $filename;; *.zip) unzip $filename;; *.Z) uncompress $filename;; *.rar) rar x $filename ;; *) echo “No extract option for $filename” esac
Note that this script also prompts for a file name if none was provided and then checks to make sure that the file specified actually exists. Only after that does it bother with the extraction.
Reacting to errors
You can detect and react to errors within scripts and, in doing so, avoid other errors. The trick is to check the exit codes after commands are run. If an exit code has a value other than zero, an error occurred. In this script, we look to see if Apache is running, but send the output from the check to /dev/null. We then check to see if the exit code isn’t equal to zero as this would indicate that the ps command did not get a response. If the exit code is not zero, the script informs the user that Apache isn’t running.
#!/bin/bash ps -ef | grep apache2 > /dev/null if [ $? != 0 ]; then echo Apache is not running exit fi
Wrap Up
Scripts on Linux system can help ensure that complicated processing is done in a consistent manner and makes running a series of commands a lot less trouble.
Copyright © 2021 IDG Communications, Inc.