If you're not yet comfortable with writing scripts on Unix and Linux systems, this post might get you off to a healthy start. Credit: Thinkstock 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 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/bash for 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. Related content how-to How to find files on Linux There are many options you can use to find files on Linux, including searching by file name (or partial name), age, owner, group, size, type and inode number. By Sandra Henry Stocker Jun 24, 2024 8 mins Linux opinion Linux in your car: Red Hat’s milestone collaboration with exida With contributions from Red Hat and critical collaborators, the safety and security of automotive vehicles has reached a new level of reliability. By Sandra Henry Stocker Jun 17, 2024 5 mins Linux how-to How to print from the Linux command line: double-sided, landscape and more There's a lot more to printing from the Linux command line than the lp command. Check out some of the many available options. By Sandra Henry Stocker Jun 11, 2024 6 mins Linux how-to Converting between uppercase and lowercase on the Linux command line Converting text between uppercase and lowercase can be very tedious, especially when you want to avoid inadvertent misspellings. Fortunately, Linux provides a handful of commands that can make the job very easy. By Sandra Henry Stocker Jun 07, 2024 5 mins Linux PODCASTS VIDEOS RESOURCES EVENTS NEWSLETTERS Newsletter Promo Module Test Description for newsletter promo module. Please enter a valid email address Subscribe