Introduction to Shell Scripting
Introduction
Bourne-again shell is the free command interpreter of the GNU project. Its name is a play on words (Bourne again / born again) referring to the historic Unix shell, the Bourne shell. Based on the latter, it brings many improvements, notably from the Korn shell and the C shell.
The original author is Brian Fox of the Free Software Foundation, later succeeded by Chet Ramey. The original Bourne shell was written by Steve Bourne.
Bash is free software published under the GPL license. It is the default interpreter on many free Unix systems, particularly on GNU/Linux systems. It’s also the default shell for Mac OS X and has been ported to Windows through the Cygwin project.
Bash uses the readline library which allows it, like the C shell, to automatically complete command and file names when typing the TAB key, which considerably speeds up work. The UP and DOWN keys allow easy navigation through command history.
Creating a Shell Script
Creating a script is very simple, just create a file and make it executable:
touch test.sh && chmod 700 test.sh
Data Streams
Shell data streams are transported through three different channels:
- standard input
- standard output
- standard error output
Standard Input
Standard input is the input data channel used by the system. By default, it’s the keyboard.
Thus, Shell commands take their parameters from the standard input.
Standard Output
Standard output is the data output channel. This is the channel through which the data resulting from the execution of a command flows. It’s usually a terminal, meaning the screen.
Thus, Shell commands very often write results to standard output.
Standard Error Output
Standard error output is the channel through which error messages pass, usually the screen. Sometimes a window is specially dedicated to this channel.
Whenever an error code is generated by a command, a message is sent on this channel.
Redirections
It’s possible to temporarily change the standard inputs and outputs during the execution of a command.
For example, you want to write to a file the list of files in a directory. The ls command allows you to list the files in a directory. This command sends the result of its search to standard output (screen).
- Example:
$ ls
amoi.c montage.jpg tp3.c
lettre.doc tp1.c zizitop.mp3
monprog.c tp2.c
To redirect standard output to a file, use the special character >.
- Example:
$ ls > liste.txt
If you display the contents of the file on the screen, you’ll see that it contains what the command should have displayed on the screen.
- Example:
$ cat liste.txt
amoi.c montage.jpg tp3.c
lettre.doc tp1.c zizitop.mp3
monprog.c tp2.c
The > character allows you to create the file if it doesn’t exist when the command is executed. If the file already exists, its content is overwritten.
To keep the file’s content intact and write to the end of it, use the special character ».
- Example:
echo "List of my directory" >> liste.txt
The echo command allows you to display text on standard output, which is here redirected to the liste.txt file, to which the character string passed as an argument is written.
- Example:
$ cat liste.txt
amoi.c montage.jpg tp3.c
lettre.doc tp1.c zizitop.mp3
monprog.c tp2.c
List of my directory
We see that the file’s content hasn’t been overwritten and that it contains an additional phrase.
The following table summarizes the special redirection characters.
Character | Description |
---|---|
> | Redirects standard output. |
» | Redirects standard output without overwriting. |
< | Redirects standard input. |
2> | Redirects standard error output. |
2» | Redirects standard error output without overwriting. |
Special Characters
In addition to the standard data stream redirection characters, the Shell has characters whose meaning is very… special. Here they are grouped in the following table.
Character | Description |
---|---|
* | Metacharacter that replaces any string (even empty). Example: cp * DATA copies all files to the DATA directory. |
? | Metacharacter that replaces any single character. |
; | Allows separating multiple commands written on the same line. Example: cp *.c DATA; tar cvf data.tar DATA copies all files with extension .c to the DATA directory and archives them in the data.tar file. |
( ) | Groups commands. Example: (echo “List:”; ls ) > liste.txt writes the string “List:” and the list of files in the current directory to the liste.txt file. |
& | Allows launching a process in the background. This allows executing other commands while a process is running. Example: netscape&. |
| | Allows communication through a pipe between two commands. Example: ls -1 | file - the file listing command (ls) sends each file to the command that allows knowing the type of a file (file). |
# | Introduces a comment. So everything that follows this character in a line is ignored by the Shell. Example: # this is a comment. |
\ | De-specializes the character that follows. That is, if the character that follows this one is a special character, then the Shell will ignore it. Example: echo Bon*jour displays bon*jour on the screen. |
‘…’ | Defines a string of characters that will not be evaluated by the Shell. Example: echo ‘*?&’ displays the special characters *?& on standard output without interpreting them. |
“…” | Defines a string of characters whose variables will be evaluated by the Shell. Example: echo “You are $USER.” displays You are + the value of the $USER variable. |
`…` | Defines a string of characters that will be interpreted as a command and replaced by the string that would be returned on standard output when executing said command. Example: echo `pwd` » liste.txt writes at the end of the file the path and name of the current directory. The special character used is obtained by the key combination: AltGr + 7 (it’s the grave accent). |
Shell Variables
Environment Variables
The Shell, like MS-DOS, has environment variables that allow keeping important information in memory such as the user’s login (stored in the $USER variable) as well as their home directory ($HOME), the list of directories in which to look for executables of external commands ($PATH), and many others…
The env command displays the list of all the Shell’s environment variables with their values.
You can display available variables with the env command.
Other Variables
Variable | Description |
---|---|
$$ | PID of the current Shell process. |
$! | PID of the last process launched in the background. |
$? | Error code returned by the last command (0: true; otherwise false). |
Declaration
The user can easily declare new variables by directly assigning a value.
Syntax: name=value
The variable’s value can be numeric or a character string, its format doesn’t matter.
Example: EMAIL=xxx@mycompany.com Manipulation
A variable can be used in any circumstance as long as it’s in the Shell. Its name must be preceded by the dollar sign ($) and be in braces ({}) if another word is contiguous to it.
Examples:
$ echo $EMAIL
xxx@mycompany.com
$ echo "My email: $EMAIL"
My email: xxx@mycompany.com
$ echo 'My email: $EMAIL'
My email: $EMAIL
In the first example, the EMAIL variable is passed directly as a parameter to the echo command which displays it after the Shell has evaluated its value.
In the second example, a string containing the same variable is passed as a parameter to echo. Double quotes are special characters ("…") that force the Shell to evaluate the value of variables contained in the string between double quotes. The echo command therefore displays the string on the screen.
And finally, this time the single quotes forbid the Shell from evaluating the value of the variable. So echo displays the raw string.
Other Examples
$ moi=deimos; echo $moi
deimos
$ phrase="Hello $moi"; echo $phrase
Hello deimos
$ rep=`pwd`; echo $rep
/home/deimos/data
In the second example, the variable is in braces so that the Shell can distinguish it from the characters that follow.
In the last example, the rep variable contains a string between grave accents, which forces the Shell to interpret it as a command and replace it with the string that would be returned on standard output when executing said command. Command Files
Command files (scripts) are text files that contain Shell commands ordered by control structures. Execution
To execute a script, several solutions:
- Syntax: sh script
This syntax launches a new Shell process that reads its commands from the script file. This file must be readable.
- Syntax: . script
The terminal is momentarily replaced by the script file that must be readable (no new process created).
- Syntax: script
Launches a new Shell process that reads its commands from the file which must be readable and executable.
- Syntax: exec script
The current Shell is replaced by a Shell process that reads its commands from the file which must be readable and executable.
Parameters
It’s possible to execute a script by passing arguments to it like any other command.
The following table summarizes the variables accessible to a script:
Variable | Description |
---|---|
$# | Number of arguments. |
$* | List of arguments. |
$0 | Command name. |
$1 | Value of the first parameter. |
$i | Value of the ith parameter if i is between 1 and 9. |
$9 | Value of the ninth parameter. |
Creating Variables on the Fly
Since bash is not a real programming language, there are many things that become difficult to do when you push it to its limits. In short, if you need to declare variables on the fly, here’s an example:
f=0
for j in `echo $nodes` ; do
f=`expr $f + 1`
local porttest_node$f=`ssh root@$node1 netstat -auntp | grep :$clientport | grep -c "LISTEN"`
done
Reading a File Line by Line
If you need to read a file line by line, as you can do in some more advanced languages, here’s an example:
while read line; do echo "$(date),$(hostname),$line"; done < somefile.txt
Capturing Signals
Capturing signals is so practical. For those who don’t understand or have no notion of these mechanisms, it’s quite simple. During a SIGHUP and other program closures, you can perform various actions using the trap command:
trap "echo \"$0 process $$ killed on $(date).\"; exit " HUP INT QUIT ABRT TERM STOP
Hiding a Password During Keyboard Input
It may be useful when a user enters something on the keyboard to hide it from the screen. This is done as follows in shell script:
save_state=$(stty -g)
echo -n "Password: "
stty -echo
read password
stty "$save_state"
echo ""
echo "You inserted $password as password"
References
Last updated 03 May 2011, 11:53 CEST.