Linux bash Shell Programming Introduction As we have seen, Linux contains its own programming language. Commands are put into a file – known as a shell script – and executed when the filename is used as a command. Recall our earlier example: We used the gedit editor to create and save the following file (called cmd1): who tty ls –lasi Remember the access permissions: You must have permission to execute the program. Grant yourself execute rights by: chmod u+x cmd1 To run the program cmd1, just type its name as follows: cmd1 (or if you have not set up your .profile use ./cmd1) Consider the following shell script: #!/bin/bash #shell script 1 echo "Today's date and time is" date echo echo –n "My username is " who am i echo –n "My current directory is " pwd The #!/bin/bash is called the ‘shebang line’. It tells the interpreter which shell should interpret this program. The # indicates that what follows is a comment and will not be processed as a command.

Exercise The ‘echo –n’ tells the shell to output the given text but to stay on the same line. Try writing and running a similar shell script. Remember to grant yourself permission to run the program. Make sure you understand how it does what it does.

An Interactive Program: read command You may wish to enter data during the execution of a shell script. Use the read command as in the following example: #!/bin/bash #Shell program 2 echo -n "Please enter your name: " read username echo "Welcome ${username}" The echo line asks the user to enter their username. The read line runs the read command which will force the shell to wait for a line of input from the keyboard. When the user enters text and presses that text will be stored in a variable called ‘username’. Finally, the last echo will output “Welcome”, followed by whatever text is stored in the username variable i.e. the text the user typed. Example run below with user input in bold and output in italics: linux-lsw5: ~/scripts $ eg1 Please enter your name: Paul Rothwell Welcome Paul Rothwell linux-lsw5: ~/scripts $ Note the use of the $ symbol in front of the variable name which is enclosed in {}. This tells the command interpreter that you want to get at the value stored in the variable and that you are not just referring to the memory location of the variable. The shell gets the text stored in ${username} and passes it to the echo command for output. If there is more than one word in the input, you can use the read command to ensure that each word is assigned to a different variable. Any words left over are assigned to the last named variable. For example, input and run this program: #!/bin/bash #Shell program 3 echo -n "Please enter your first name and surname: " read firstname restofname echo "Your first name is ${firstname}" echo "and your surname is ${restofname}"

Exercise Write a shell script which invites a user to enter his/her name and invites the user to enter their username. The program should then echo to the screen a

welcome message to the user which includes their name, username, home directory, and the current date and time. A user’s home directory is stored in a a variable called HOME When you run the script, the output should look something like this (user input in bold): Good day, please enter your name: Paul Please type in your username: rothwell Welcome Paul Your username is rothwell Your home directory is /staff/rothwell Today's date and time is Friday October 9 17:04:01 IST 2015 Notes

 

The bold text has been entered by the user. The second line of your script should contain your name + exercise title as comments (use #)

More on Variables Two important general notes 1. When assigning values to variables using ‘=’ ensure there are NO spaces either side of the ‘=’. 2. When accessing the values of variables, ALWAYS enclose the variable name inside "${ }". E.g. the value of variable x is written "${x}". Try these commands on the command line and observe the effects (you can omit the comments): x='hello there' echo "${x}" echo "${y}"

#create x and give it the value ‘hello there’ #examine the contents of x #examine contents of uncreated variable

What happens? x='hello there' #create x and give it the value ‘hello there’ Nothing happens on the screen but the variable has been created and stored. echo "${x}" The output is ‘hello there’, the contents of variable x: hello there echo

"${y}"

A blank line is printed on the screen because the variable y has no value. The shell does not generate an error. To examine the contents of a variable you use the echo command as above. Remember, the variable name must ALWAYS be preceded by a dollar ($), surrounded by braces { } and enclosed in double quotes (" ") whenever you want to get at its contents. You can see all of the shell variables that have values using the ‘set’ command. Try it: set Set will display all the variables that have been set in your shell. The following example list explains some common ones –

Do not type these in: HOME=/staff/rothwell /* home directory as shown */ LOGNAME=rothwell /* login name */ PATH=/usr/bin:/usr/ucb:/etc:.:${HOME} /* sequence of directories searched by shell for command programs; note that the current directory (.) is included. */ PS1=$ /* Prompt String 1 (normal prompt) */ PS2=> /* Prompt String 2 (appears when the shell expects more for the command) */ PWD=/staff/rothwell /* Present Working Directory */ SHELL=/bin/bash /* Shell in use */ x=hello there /* user created variable */ The values of any of these variables can be displayed on the screen using the ‘echo’ command. For example: echo "${HOME}" /staff/Rothwell echo "${SHELL}" /bin/bash

A note on error messages Errors should be echoed to the standard error channel and adhere to the following standard syntax. The echo command is used to display messages. However, as it normally sends its output to the standard output channel, the output for an error message needs to be redirected to the error channel.

In the following example 1>&2 redirects the standard output to the error channel. "${0}" always evaluates to the name of the script that contains the code. It is always output with the error message so that the user can see which script is reporting the error. When a fatal error is reported the script should be aborted. In that case it should return a ‘false’ exit status so that any program that uses the script as a condition in an ‘if’ command will behave correctly. In Linux, an exit status of zero is true and is the default exit status. Any non-zero positive integer between 1 and 255 is ‘false’. Normally each different error situation should be signalled with a different number in this range. Documentation of the script can later identify the meanings of all the exit status numbers. For example: echo "${0}: ERROR: Could not create directory ${rdir}." 1>&2 echo "${0}: USAGE: Check permissions and disk space available." 1>&2 exit 1 #abort program with exit status 1 Which, in an example run where egcmd is the name of the script and "${rdir}" has the value ‘xyz’, would display on the error channel as: egcmd: ERROR: Could not create directory xyz. egcmd: USAGE: Check permissions and disk space available.