The shell is a program within a Linux or Unix operating system which allows you to enter commands for execution by the system. When a terminal window is opened on a linux computer, it starts the shell program which presents an interface to enter commands. This interface is known as the command line interface. When a command is entered, it is executed by the shell and the output is displayed on the screen.
In addition to being able to accept and execute commands interactively, the shell can also execute commands stored in a file. This mode of execution is known as shell scripting, and in this article we cover the basics of shell scripting.
1. History of the Shell
Starting with Unix in the 1970s, there was a shell program called the V6 Shell developed by Ken Thomson. It was an interactive shell and lacked scripting ability.
It was followed by the Bourne Shell in 1977 and remains in use today as the default shell for the root account. This shell added scripting abilities which has proved extremely useful in practice through the years.
Further development of the shell in the 1980s gave rise to many popular shell variants, the most popular of which were the C-Shell and the Korn Shell. Each of these shells brought its own syntax which, in certain cases, was drastically different from the original shell.
One of the most popular shells today is the Bash Shell. Bash stands for Bourne-Again-Shell and is a vastly improved variant of the original Bourne Shell.
In this article, we describe shell scripting for the Bash Shell.
2. Executing a Shell Script
How do you execute a shell script? Simple. Just pass the script path as an argument to the shell:
A sample shell script:
echo "hello world"
Run it as follows:
$ bash hello.sh # prints hello world
Note: The shell requires lines to be terminated by LF characters (Line-Feed). If you write your shell script on Windows and try to execute it directly on a Linux system, you may run into errors. Windows uses CR-LF combination (Carriage-Return-Line-Feed) for line termination. This needs to be converted to LF only. Check your Windows editor for ways to do this.
There is another way to execute a shell script directly as a command. Insert the following line (the hashbang declaration) as the first line of your shell script.
With this change, our simple shell script is now:
#!/bin/bash echo "hello world"
Now, you need to make the script file executable as follows:
$ chmod +x hello.sh
At this point, you can execute the script file directly without having to reference the shell explicitly.
$ hello.sh # prints hello world
Let us now look at some advantages of using shell scripts.
3. Task Automation
The first advantage of using shell scripts is automating frequently executed tasks. Suppose you have a task which you need to perform everyday. If you need to execute multiple commands on your linux system everyday, you can store these commands in a file and run the script. Examples include:
- Archive and upload a file or folder everyday to a cloud storage facility such as S3.
- Compress log files which tend to grow everyday.
- Fetch stock prices, parse the fetched data, and trigger an email or SMS when certain conditions are met (too high or too low prices).
4. Combining Multiple Commands
In addition to automating frequent tasks, you might also find it advantageous that you can combine multiple sequences of commands into a single command. Remembering a single command is much simpler than multiple commands, not to mention the order in which they must be executed.
An example would be the boot-up sequence of the Linux Operating System itself. As a part of boot-up, the OS executes a number of commands to get the system into a proper state. These commands are actually shell scripts which live under the /etc directory. If you take a look at one of these shell scripts, you will realize the complexity of booting a system, which you might have had to perform by hand in the absence of shell scripts.
The following is a sample shell script, /etc/profile, which is executed each time a user logs in. Imagine typing in these commands by hand!
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1)) # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...). if [ "$PS1" ]; then if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then # The file bash.bashrc already sets the default PS1. # PS1='\h:\w\$ ' if [ -f /etc/bash.bashrc ]; then . /etc/bash.bashrc fi else if [ "`id -u`" -eq 0 ]; then PS1='# ' else PS1='$ ' fi fi fi # The default umask is now handled by pam_umask. # See pam_umask(8) and /etc/login.defs. if [ -d /etc/profile.d ]; then for i in /etc/profile.d/*.sh; do if [ -r $i ]; then . $i fi done unset i fi
5. Easier to Develop
It is possible to perform the same actions as a shell script inside a regular program written in C/C++. However, it is far easier to write and debug a shell script than a C/C++ program. Especially for system administration tasks which include execution of external commands, creating and removing files and directories, redirecting output, etc.
C/C++ programs are better for a much lower level of operation, such as invoking system calls, manipulating data structures, etc.
A shell script, by virtue of being a text file, can easily be viewed to check out what actions it is performing. By contrast, the only way you will ever know what a program written in a language such as C/C++ (and compiled to an executable) is doing is if it chooses to tell you or if you have access to the source code. For example, you can check if a shell script is deleting any files, and if you need those files, you can copy them to a different location.
It is also much easier to diagnose problems with shell scripts rather than regular programs since you can look at the source code. Is that script failing because a directory does not exist? You can look in the script code and create the directory (though a well-behaved shell script should check and create it to avoid such errors).
A shell script can be transferred to other Unix and Unix-like operating systems and executed (if the shell itself is present). Even when transferring a shell script from different architectures such as x86, MIPS, Sparc, etc, shell scripts are much more portable than C/C++ programs.
The only way a C/C++ program can be transferred and used on another system is to copy the source code, build the program, and attempt to run it. Even then, it may not work as expected if it uses architecture-specific code.
Now that you have an idea what shell scripts are and their many advantages, wouldn’t you like to use them for your tasks? What issues have you faced when using them? Please let us know in the comments below.