UNIX Shell Scripting Basics

Understanding UNIX shell scripts
1. Command-line processing
The UNIX shell is a command-line interpreter that processes each command or combination of commands on a command line when you press Enter. This example shows only a single command on the command line. $ sort -r userlist You can combine multiple commands on the same command line by creating a composite command. This example shows a composite command comprising the ls and less commands. $ ls -l | less You can use a number of special characters in the command line. A semicolon (;), for example, allows you to place more than one command statement in the same command line. When you enter the code, the shell executes the preceding commands only when it reaches the semicolon. In this example, the shell executes the cp command statement and then the cat command statement. $ cp list list.bak; cat list.bak Special characters you can use to manipulate commands in the command line include y y y y y backslash (\) greater than (>) less than (<) pipe (|) ampersand (&)

backslash (\) The backslash (\) character prevents the shell from treating another character as a special character through a process called backslash escaping. This allows you to split a command statement across multiple lines. When you place the backslash at the end of a line and then press Enter, you can continue the statement on the next line. The backslash prevents the shell from treating the Enter keystroke ± or new line

character ± as a special character. This example shows a long echo statement carried across three lines. The code for this is $ echo Long pieces of text may not always fit onto a single \ > line of the command line interface, so it becomes \ > necessary to split them across multiple lines using \ > backslashes. greater than (>) The greater-than character (>) allows you to direct the standard output of a command to a file or a device such as a printer instead of to the terminal screen. This example will send the output of the ls command to a file called userdirs. The code for this is $ ls -l /usr/home > userdirs less than (<) The less-than character (<) allows you to send the contents of a file to a command as its standard input. This example sends input from a file called list to the sort command. The code for this is $ sort -d < list pipe (|) The pipe character (|) allows you to direct the output of one command to the input of another command. This example pipes the output from the cat command as input to the grep command for further processing. The code for this is $ cat EasyNomad | grep 'South America' ampersand (&) An ampersand (&) character at the end of a command statement allows you to run commands in the background.

This example specifies that the find command will run a long search process in the background. The code for this is $ find 'EasyNomad' & [1] 48748 $ EasyNomad If you want to use special characters in command-line text without the shell recognizing them as special characters, you have to enclose them in quotes or precede them with a backslash (\). This example shows an echo command in which the echo text contains an ampersand. There's a backslash in front of the ampersand, which prevents the shell from treating it as a special character. $ echo Tours \& Accommodation Tours & Accommodation $

Question
How do you think the shell processes the contents of a command line in order to execute it? Options: 1. 2. 3. 4. By analyzing commands first and then proceeding to options and arguments By dividing the command line into segments and processing each segment By processing the command line from beginning to end, one character at a time By processing the command line from beginning to end, one word at a time

Answer
When you execute a command line, the shell looks for spaces and special characters and splits the command line into segments wherever these characters occur. It then processes each segment in turn. The segments into which the shell divides a command line are called tokens. To execute a command line, the shell processes the first token and then each subsequent token in turn. To begin processing a token, the shell checks whether it's a keyword, an alias, or an ordinary word.

If the token is a keyword that opens a substructure such as a function, conditional statement, or bracketed group of commands, the shell processes the substructure before moving on to the next token. If a token is an alias, the shell replaces it with the command to which the alias is mapped. If a token is an ordinary word such as a command or a filename, the shell processes it directly. After comparing a token against the list of known keywords and aliases, the shell processes it using several stages of expansion and substitution. Expansion and substitution takes place in the following sequence: y y y y y y y brace expansion tilde expansion parameter substitution command substitution arithmetic substitution word splitting pathname substitution

brace expansion In brace expansion, the shell looks for braces ({}) ± also called curly brackets ± in the token. If braces are present, it expands their contents. For example, the token b{all,ook} expands into ball book. tilde expansion In tilde expansion, the shell looks for tildes (~) in the token. If a tilde is present, it replaces the tilde with the location of the current user's home directory. For example, depending on the system configuration, the token ~vincep/file2 might expand into /usr/home/vincep/file2. parameter substitution In parameter substitution, the shell checks whether the token is a variable name preceded by a dollar sign ($). If it is, the shell replaces the token with the current value of the corresponding variable. For example, if the value of the SHELL parameter is /bin/ksh, the token $SHELL is replaced with /bin/ksh. command substitution In command substitution, the shell checks whether the token is a command enclosed in brackets and preceded by a dollar sign ($). If it is, the shell processes the command and

the shell examines those parts of the command line that have resulted from previous stages of expansion and substitution. and pathnames. it splits them into tokens for processing. denoted by a semicolon or a new line character.txt funding. For example. pathname substitution In pathname substitution. 3. For example. the token $(type username) might be replaced with vincep. If it is. Then it matches the command against its list of known functions. the token f*. the shell looks for wildcard characters in the token. & | . it searches the current directory for filenames that match these wildcards and substitutes them for the token.txt might expand into fares. 2. question marks (?).replaces the token with the command's output. word splitting In word splitting.txt. or double slashes (//). the shell evaluates the expression and replaces the token with the result. After performing expansion and substitution. the shell checks whether the token is an arithmetic expression enclosed in double brackets and preceded by a dollar sign. \ . Question Which special character is used to run a command in the background? Options: 1. 4. depending on the files in the current directory. it executes the command to produce output. built-in commands. It then moves on to the next command. If any of these contain spaces or special characters. Once the shell has identified which command it needs to execute. For example. the shell processes subsequent tokens until it reaches the end of a command. If it finds asterisks (*). the shell replaces the token $((72/9)) with 8. arithmetic substitution In arithmetic substitution.txt flights. processing its tokens in the same way.

Also. Options: 1.) is used to combine separate commands on the same line. Question Choose the code that contains an example of command substitution. In this example of command substitution. The ampersand symbol (&) is used at the end of a command. The backslash (\) is used to prevent special characters from being interpreted in such a way that their literal values are used in stings. The path ~/documents expands to the documents folder in the home directory of the current user. The contents of the hostname file are used as a search term by the grep command.com > hosts ls * | grep "easynomad" Answer The code $(cat /etc/hostname) is an example of command substitution. Jobs in the background are assigned a job id number. you can continue your command on a new line by typing a backslash before pressing Enter. Commands on the right of the semi-colon are only interpreted once commands on the left have been interpreted and executed. 3.2. to run a job in the background. 2. Option 3 is incorrect. . This is an example of tilde substitution. Option 4 is incorrect. Option 2 is incorrect. 4. You can you can use this number to foreground the job again. cat logfile | grep $(cat /etc/hostname) cd ~/documents echo server{1. Option 1 is correct. Option 2 is incorrect.easynomad. Option 1 is correct.Answer The ampersand symbol (&) is used to run a command in the background. so that its output can be substituted into the grep command.3). the command cat /etc/hostname is processed before the grep command is executed. The pipe (|) special character allows you to use the output of the command on the left of the pipe as input for the command on the right of the pipe. The semi-colon (.

the ls command executes without errors ( so its exit state is zero. Daniel CARUSO. For example. you can use a first command to check whether a file exists and a second command to perform an operation on it if it exists. The code server{1.2. 3. Maria GARZA. 4.Option 3 is incorrect. 2. Because it does exist.easynomad.easynomad. In this example. Greg . Because the command terminates Because the command's exit status is zero Because the command's standard error output is null Because the command's standard output contains no error messages Answer The shell knows that a command has executed successfully when the exit status of the command is zero.com is expanded as: server1.3). you join the commands using a double ampersand (&&). Teresa LOGAN. To make one command conditional on another.easynomad. server2. the ls command checks whether the userlist file exists. This is an example of filename substitution. $ ls userlist && sort userlist userlist BAKER.easynomad. Command grouping You can join commands on a command line in such a way that the second command executes only if the first command has executed successfully. The command after the && symbols executes only if the command before the && symbols produces a zero exit status ± in other words.com. if it executes successfully.com. Question How do you think the shell knows whether a command has executed successfully? Options: 1. The code ls * lists every file in the current directory. server3. 2. Option 4 is incorrect. This is an example of brace expansion. This causes the sort command to execute.com.

In this case. This allows you to redirect input and output to and from a group of commands. In this example. Molly STROTHER. $ ls userlist || touch userlist userlist $ You can group commands using braces ({}). Sam PASCUCCI. If it fails to find the file. Debora $ If you delete the userlist file and run the command again. . Because the sort command is conditional. The shell treats any command block enclosed in braces as if it were a single command. the shell doesn't attempt to execute it. $ ls userlist && sort userlist ls: userlist: No such file or directory $ You use a double pipe (||) to make a command conditional on the unsuccessful execution of the previous command. Sarah NOVAK.MANEROWSKI. Vince REILLY. the ls command looks for a file called userlist. Tanya WADE. this means that the file already exists. the second command executes only if the first command has a non-zero exit state. In this example. the ls command encounters an error ± so its exit state is non-zero. In such a case. $ ls userlist || touch userlist ls: userlist: No such file or directory $ If the ls command executes successfully. Glen OSWALD. the touch command creates it. Nicholas NOVIALLO. the braces group the sort and grep commands into a code block so that the shell sorts input and then extracts any lines containing the word Mexico. the touch command doesn't execute.

the code specifies the flights file as input and the mex_flights file as output. it will get overwritten. Option 1 is correct.com > hostname cat hostname | echo easy1.easynomad. 3. The && conditional execution symbol ensures that if the attempt to list the hostname file succeeds.easynomad. You use the double pipe to make a command conditional on the unsuccessful execution of a previous command. This allows you to define variables that exist only for the lifetime of the subshell.easynomad. . This causes the shell to spawn a subshell and execute the command block in the subshell.com > hostname Answer The use of the || ensures that the code that writes the output from the echo command to the hostname file will only execute if the attempt to list the hostname file fails. Which line of code will enable you to do this? Options: 1.com.com > hostname cat hostname >> echo easy1. In this example.easynomad. $ {sort | grep 'Mexico'} < flights > mex_flights $ You can group commands using round brackets ± often called parentheses ± instead of braces. $ (sort | grep 'Mexico') < massivefile > mex_info $ Question You want to create a file named hostname and containing the text easy1. 4. Option 2 is incorrect. and to change the working directory within the subshell without affecting the parent shell.com > hostname cat hostname && echo easy1. Commands that execute in a subshell do not affect what's happening in the main shell. you don't want to overwrite any existing file by that name. However. cat hostname || echo easy1. 2.$ {sort | grep 'Mexico'} You can redirect input and output to a command block as if it were a single command.easynomad.

This is necessary because some commands run differently in different shell programs. shell scripts contain commands. You can read and edit ordinary text files. They contain commands They have a specific filename suffix They have an introductory line of code that defines them as scripts You can execute them Answer Unlike ordinary ASCII text files. The >> redirector is used to append output to a file. Question What do you think distinguishes shell script files from ordinary ASCII text files? Options: 1. The contents of shell scripts are stored as ordinary ASCII text. 3. 3. Therefore. . you need to be able to execute shell scripts. 2. are executable. In such cases. you may need to run larger pieces of code that include several lines or to use the same piece of code many times. You can store blocks of shell commands in shell scripts. but you cannot execute them.Option 3 is incorrect. you have to assign executable permissions on script files. The first line in any shell script has to be a special line of code that specifies the particular shell program in which the script must run. However. 4. it's advantageous to store the code in a file. However. The I symbol pipes the output from one command into another command as input. Option 4 is incorrect. Storing commands in scripts Command grouping is useful for executing relatively short command-line code that you need to run only once. and have an introductory line of code that defines them as scripts.

2. You can execute it directly from the command line or you can invoke it from inside other scripts. Once you've created a script and made it executable. 4. either one or more of the owner.The shell identifier at the beginning of a shell script consists of a hash followed by an exclamation point (#!) ± commonly called a shebang ± and the absolute pathname of the shell program. This example shows the first line of a script that uses the Korn shell. or other executable permissions must be set. Option 3 is correct. Option 2 is incorrect. Because shell scripts are simple ASCII text files. The first line of a shell script identifies the command interpreter. Question Identify the statements that correctly describe shell scripts. Option 1 is correct. so they don't contain binary code and aren't compiled. #! /bin/ksh This simple example of a script tests whether the directory /usr/shared/tours exists. . Then it creates a file called tourlist inside this directory and returns a message. If it doesn't. Options: 1. you can easily create them in a text editor such as vi or emacs. Shell scipts are interpreted by the command interpreter. group. Because shell scipts are executed. Shell scripts are ASCII text files Shell scripts need to be compiled prior to execution Shell scripts need to have executable permissions set The first line of a shell script is used to identify the command interpreter Answer Shell scripts are ASCII text files that need to have executable permissions set. #! /bin/ksh ls /usr/shared/tours || mkdir /usr/shared/tours touch /usr/shared/tours/tourlist echo tour directory and tourlist file created. you can use it as many times as you like. 3. the script creates it.

For example: #!/bin/bash Summary You can use special characters to join commands on a single command line.Option 4 is correct. All other logos or trademarks are the property of their respective owners. You can execute shell scripts directly from the command line and reuse them as often as necessary. When you execute a command line. Storing commands in scripts | | Summary | Copyright © 2003 SkillSoft. | Print | Contents | Close | Creating an executable file in UNIX Learning objective . Command grouping | | 3. You can join two commands so that the second command will execute only if the first command executes successfully or only if it executes unsuccessfully. You can prevent the shell from recognizing a special character by preceding it with a backslash. Table of Contents | Top of page | | Learning objective | | 1. You can group commands using braces or brackets. which cause the shell to treat the commands as a single command. You can store blocks of commands in a text file called a shell script and make this file executable. to redirect input and output. to run commands in the background. the shell splits it into tokens and processes each token in turn. The first line of a shell script consists of a hash symbol followed by an exclamation mark and the absolute path to the command interpreter that will be used to execute the script. All rights reserved. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. and to continue a command over multiple lines. Command-line processing | | 2.

you open a text file in a text editor such as vi or emacs. Question You need to invoke the Korn shell at the beginning of the script. see if you can complete the code that does this. #!/bin/ksh clear echo "Please enter the name of the new travel package: " read PNAME ls /usr/shared/$PNAME || mkdir /usr/shared/$PNAME cd /usr/shared/$PNAME . you should be able to create and run a simple shell program. 1. the shell script needs to prompt the user to supply the package name. The names you need to use for the new files and directories depend on the names of the travel packages. and you need to create "bookings" and "info" subdirectories in the package directory. let's say that you decide to write a shell script for the Korn shell that automates the repetitive task of creating a file and folder structure for a new travel package. Assuming that the path to the Korn shell is /bin/ksh. It then needs to read the name and store it as a variable.After completing this topic. Therefore. Creating a shell script To create a shell script. #!/bin/ksh clear echo "Please enter the name of the new travel package: " read PNAME You need to create a directory for the new package in /usr/shared. For example. You open a new text file in vi and ± in this case ± name it add_pkg_files. MISSING CODE Answer You type #!/bin/ksh to invoke the Korn shell at the beginning of the script. You do this using a series of mkdir statements.

you want the script to display a message to the user that confirms that the files and folders have been created successfully. You do this using a series of touch statements. you can confirm its existence using the ls -l command. In this example." After you've saved and closed the text file containing your new script. and one for bookings.mkdir bookings mkdir info You need to create three empty text files in the new folder hierarchy ± one for flights. #!/bin/ksh clear echo "Please enter the name of the new travel package: " read PNAME ls /usr/shared/$PNAME && mkdir /usr/shared/$PNAME cd /usr/shared/$PNAME mkdir bookings mkdir info touch /bookings/$PNAME_bookings touch /info/$PNAME_accom touch /info/$PNAME_flights Finally. one for accommodation. you've called the script add_pkg_files. $ ls -l total 2 -rw-r--r-$ 1 vincep vincep 326 Feb 11 11:56 add_pkg_files . Therefore. This command reveals that the file doesn't have execute permissions set for it. you can't run it as a script. #!/bin/ksh clear echo "Please enter the name of the new travel package: " read PNAME ls /usr/shared/$PNAME && mkdir /usr/shared/$PNAME cd /usr/shared/$PNAME mkdir bookings mkdir info touch /bookings/$PNAME_bookings touch /info/$PNAME_accom touch /info/$PNAME_flights echo "Files and folders for $PNAME created in /usr/shared.

On the other hand. $ ls -l total 2 -rwxrwx--$ 1 vincep vincep 326 Feb 11 11:56 add_pkg_files . You can do this by specifying the script's permissions as 755. you use the letters r. you don't want general users to be able to use the script at all. In this case. write. you would need to specify the script's permissions as 770. and execute permissions respectively. $ chmod +x add_pkg_files $ In numeric form. In symbolic form. To make a script executable using symbolic form. $ chmod 755 add_pkg_files $ Let's say that you're a member of a group of developers and you want other members of the group to be able to edit your script. but you don't want anyone else to be able to write to the script. and execute permissions.When you specify a set of permissions. and the third to all other users. with 0 specifying no access and 7 specifying read. and x to denote read. you specify permissions using a three-digit octal code. you need to specify the permissions that apply to y y y the file's owner users in the file owner's group everyone else You can specify permissions in either symbolic or numeric form. The numbers from 0 to 7 represent increasingly open permissions. write. the second to the owner's group. $ chmod 770 add_pkg_files $ Running ls -l again reveals that the script file is now executable. Let's say that you need to allow everyone to execute a script. w. The first digit applies to the file's owner. you use the chmod +x command.

Question If the octal mode value of a shell script's permissions is 740. 3. Any user Only member of the group that owns the file Only the user that owns the file Only users who are logged on locally Answer In this example. Option 1 is incorrect. 2. . Everyone File owner Group Local login Answer You can assign permissions to the individual user that owns the file. general access to the file ± as represented by the 0 in the permissions octal ± is denied. Option 3 is correct. and to everyone else. 4. who will be able to run the shell script? Options: 1. Option 4 is incorrect. File system permissions aren't affected by whether users are logged in locally or remotely. 4. Options: 1. Option 2 is incorrect. so they have full permissions to the file and can execute it. In this example. The file owner's permissions are represented by the 7. In this example. the permissions of members of the group that owns the file is represented by a 4 so they can read the file. 2. only the file owner has the executable permission assigned ± so only they can run the shell script. to the group that owns the file. but can't write to it or execute it. 3. Question Identify the levels at which you can assign permissions.

and specifying the path to the script as well as the script name. Instead you use the group ownership of files to control access. the user who creates a file owns it. Option 3 is correct. The script executes in the subshell. Option 4 is incorrect. preceded by . invoking the shell Invoking the shell to execute a script involves running an instance of the shell. you can specify its full file path. You can set permissions for anyone that tries to access the file. To run the add_pkg_files script using direct execution. regardless of your current working directory. also called a subshell. and usually has full permissions to the file. This allows you to specify shell options. which returns you to the main shell once the script has finished running. You navigate to the directory in which the script is stored and type its name at the shell prompt. This allows you to execute the script by simply typing its name. you type .Option 1 is correct. ./. Instead of navigating to the script's directory./add_pkg_files at the command prompt. This causes the shell to spawn a child shell process. you would set the read permission in the third permission set. the user who creates a file is part of a primary group that also owns the file You use group permissions to control who can access a file and what they can do with it. Option 2 is correct. By default. 2. using your environment Using your environment to execute a script requires that the script is located in a directory that is found in the $PATH environmental variable. Running a shell script You can execute a shell script by y y y executing it directly invoking the shell using your environment executing it directly Direct execution is the simplest way to execute a script. If you want everyone to be able to read a memo in a shared directory. By default. You can't assign permissions at local login level.

In some UNIX shells the keyword source is replaced by a period (.profile file. which allows you to use the main shell while the subshell executes the script. In this case. This causes the current main shell to run each command in the script in sequence. 3. for example. Run a script at a specified future time Run a script regularly at a specified interval Run a script when system load levels are low Run a script when the system is offline Answer . What do you think you can use the shell to do? Options: 1. $ .$ . you don't need to use ./add_pkg_files You can run the script in the background. you type /bin/ksh add_pkg_files. $ /bin/ksh add_pkg_files If you have added your script directory to the $PATH statement in your . As with direct execution. You can't do anything else with the main shell while the script is executing. This causes the script to run in a subshell.) $ source add_pkg_files Question You may not want to execute a script immediately. $ add_pkg_files If you don't want to run the script in a subshell./add_pkg_files & You can run the script by invoking the shell. the script runs in a subshell./ or the shell to run the script. 4. you only need to type the name of the script. To do this in the Korn shell. you can precede it with the keyword source. 2.

When you run a script with the batch command. at 2. cron Targets: A. specifying the name of the script and the interval at which to run it. $ cron You use the batch command to run a script as soon as system load levels are low. which starts a process that checks the /etc/crontabs file each minute and executes any jobs scheduled for the current minute. Options: 1. You need to make an entry in the /etc/crontab file. You can also use more informal time specifications like 1pm tomorrow or even teatime. you specify that the script must run at 6:00 pm on October 12. $ at 6pm Oct 12 add_pkg_files You use the cron command to run a script at regular intervals. at regular specified intervals.5. $batch add_pkg_files Question Match the commands to their descriptions. Then you run the cron command. or whenever system load levels are low. In this example. Runs scripts when system resource usage is low B. Runs scripts at a specified interval C. which means 4:00 pm. Runs scripts at a specified time Answer . the shell queues it as a pending job until the system load average falls below 1.You can use shell commands to run a script at a specified future time. batch 3. You use the at command to run a script at a specified future time.

It is used when the location of the file is not listed in the $PATH variable. The cron command allows you to specify the interval at which a command will repeat. It's useful if you need to set options for the subshell./addfile.sh Answer The source command executes the commands in a target file as if they were entered into the current shell.sh file is listed in the $PATH variable Option 2 is incorrect. You can use a variety of formats.sh file in a subshell.sh. 3. The . 4. days of the month. This method launches a subshell in which the script is executed.sh /bin/bash addfile.sh . . The batch command is useful if you want to run scripts at times when they won't interfere with system performance./ syntax only allows you to execute the addfile.sh source addfile. and the batch command to run scripts when the system is relatively idle. The amount will vary according to your system. including keywords such as "noon" and "today". The at command allows you to specify the time and date at which a script will run. You want to run the script in the current shell. Option 3 is incorrect. Option 1 is incorrect. Question You have logged in as gregl and navigated to /home/gregl/bin. It runs commands or scripts when system load levels drop below a specific amount. It is used when the location of the addfile. or specific months. hours. 2. This method executes the script in a subshell. addfile. which contains a shell script named addfile. It can be set to recognize minutes. days of the week. Which command should you use? Options: 1. the cron command to run commands at a regular interval.You use the at command to run commands at a schedule time.

Option 4 is correct. The source command reads the contents of the referenced file directly into the current shell. It's useful if you want to apply changes to your .profile file during your current session.

Summary
To write a shell script, you begin by invoking a shell. Then you add lines of commands that perform the required tasks. You save the file and make it executable by assigning execute permissions to it. You can run a shell script by invoking it directly or by invoking it through the shell. Both these processes cause it to run in a subshell. Alternatively, you can run a script in the main shell by using the source keyword. If you include your script directory in the $PATH statement of the .profile file, you can run a script simply by typing its name at the command prompt.

Exercise: Writing a UNIX shell program
A note about exercises

This exercise is designed for practice use and does not contain new learning content. If your computer doesn't have an application or applications required to carry out the exercise tasks, or if you would prefer to perform the exercise at another time, you can proceed to the next topic. Scenario
You currently use a text file as a signature file for your e-mail messages. It contains your name, job description, and contact details. You decide to liven it up a little by writing a script that customizes it with a different message every day.

Exercise
Your assignment for this exercise is to write a script that customizes your e-mail signature file ± called mysig ± with a random message. You generate the messages using the fortune command, which outputs a random snippet of wisdom each time you run it. The fortune program is located in /usr/games. You don't need to supply any options or arguments to the fortune command. You need to incorporate the fortune message in your signature file. You need to use the cp command to make a temporary copy of mysig called dailysig. This file prevents a buildup

of previous fortune messages by storing a single message for each day only. Finally, you append the output from fortune to dailysig by redirecting to dailysig. The shell you're using for this script is the Korn shell, which is located at /bin/ksh.

Task list
Number 1 Instructions Write a script for the Korn shell that uses the fortune and cp commands ± as well as output redirection ± to customize your e-mail signature file with a random message.

Review your solution and, when you are satisfied with it, open the solution page.

Table of Contents
| Top of page | | Scenario | | Exercise | | Print | Contents | Close |

UNIX command execution
Learning objective

After completing this topic, you should be able to manage the execution of UNIX shell commands.

1. Using the command line
In UNIX, shell programs provide an interface between users and the kernel ± the core of the operating system. You interact with the kernel by entering commands at the shell prompt. It's possible to enter several commands at once. In this case, you separate each command using a semicolon (;). The code shown here redirects the output of the ls command to a file called listing, and then uses the cat command to display the contents of the file. Because the two commands are separated by a semicolon, they run consecutively.

$ ls -l /home > listing ; cat listing lrwxrwxrwx 1 root wheel 9 Oct 30 13:53 /home -> /usr/home $ If you end a line of code with a backslash (\), pressing Enter will move you to a new line and allow you to continue entering commands. You can continue to do this over multiple lines. When you run the commands, the shell will execute your code as if it were one long line, ignoring the backslash characters. You use backslash characters for improved readability. $ echo This is a very long line of \ > text, wrapped with a backslash This is a very long line of text, wrapped with a backslash $

Question
Most shell commands behave as filters ± they can take data as input, process it, and provide output. Because of this behavior, you can chain commands together, piping the output of one command into the input of another command. You do this using the pipe character (|). See if you can pipe the output of the ls -l command to the less command.

$ MISSING CODE

Answer
You type ls -l | less to pipe the output of the ls -l command to the less command. Sometimes you may want to run commands in the background, especially if they're likely to take a long time to complete. Background commands use idle CPU time only, allowing you to get on with other things. You can background any command by suffixing it with an ampersand character (&). The code shown here will run a script called myscript.sh in the background. $ ./myscript.sh & [1] 34030 $

Question
Which statements about using the command line are true? Options: 1. 2. 3. 4. You use a backslash (\) to wrap commands across multiple lines You use a forwardslash (/) to prevent special characters being interpreted You use an ampersand (&) to run commands in the background You use a semi-colon (;) to separate commands that execute consecutively

Answer
You use the backslash to make long commands more readable, the semi-colon to enter consecutive commands on the same line, and the ampersand to run commands in the background. Option 1 is correct. Provided you precede it with a backslash, you can use the Enter key to continue long commands on a new line. The shell will run your command as one long line, ignoring the backslashes. Option 2 is incorrect. The forwardslash does not prevent special characters from being intepreted. It is used in the syntax for describing the filesystem. Option 3 is correct. The ampersand allows you to run commands in the background on idle processor cycles, leaving you free to continue working in your current session. Option 4 is correct. You can use the semi-colon to combine commands that execute consecutively on a single command-line. This is useful when the first command will take a long time to complete.

2. Conditional execution
Conditional execution is a programming strategy that allows you to specify different actions based on the outcome of an initial operation. For example, you could create a shell script that checks the size of a log file and then backs it up only if it is larger than a certain size. Regardless of their type or function, most UNIX commands return an exit status number to the shell when they've completed executing. The exit status indicates whether a command executed successfully. If a command executed successfully, it returns a value of 0 to the shell. Greater values indicate an error of some sort.

the second command will execute only if the first command exits successfully ± returning a zero exit status. And if the second command fails. A non-zero exit status indicates that a command did not execute successfully 2.Although you never see exit statuses at the shell prompt. For example. Most shells provide at least the following two pairs of operators for performing conditional execution based on exit status values: y y double pipe (||) double ampersand (&&) double pipe (||) If you separate two commands with two pipe characters (||). while an exit status of 0 indicates that it did complete successfully. An exit status of 0 indicates that a command completed successfully 3. . Any non-zero exit status is a failed command. It's possible to combine conditional execution operators to produce complex code. Option 1 is correct. Options: 1. The range of possible non-zero values for the exit status depends on the command that you execute. Question Identify the statements that correctly describe conditional execution. Conditional execution allows you to choose an action based on the exit status of a command 4. Conditional execution allows you to choose an action based on the exit status of a command. you can use them to include conditional decisions in your shell scripts. double ampersand (&&) If you separate two commands with two ampersand characters (&&). Conditional execution allows you to choose what code to run based on the output of a command Answer A non-zero exit status indicates that a command did not execute successfully. and the shell you use. the second command will execute only if the first command returns an error ± a non-zero exit status. the third command will not run. in the syntax shown here. the second command executes only if the first command fails.

in which the exit status is stored. Option 1 is incorrect. You can use the test command to return an exit status after testing for a particular value. Option 3 is correct. You use the && operator to ensure that a new hosts file is only created if the command to rename the original succeeds. Question You are creating a script that writes to the filesystem. . and the && operator will cause the hosts file access and modification times to be updated. This will cause the touch command to execute and create a new hosts file. not their results. It is safe to overwrite the hosts file if the command that renames the original file. touch hosts oldhosts && cat oldhosts && touch hosts Answer The || operator ensures that the hosts file is not overwritten if it already exists. The || operator will execute if the hosts file doesn't exist and the ls command returns a non-zero exit status. The . The execution of the command to overwrite the hosts file is not dependant on the exit status of the command listing the host file. Which commands are safe to use? Options: 1. Option 4 is correct. and you don't want to alter any existing files. the value of the $? Variable. operator merely allows consecutive execution of commands. as well as the command that prints the contents of the renamed file. complete successfully. Option 2 is correct. Depending on the conditional operator you use. 3. will be 0. ls ls ls mv hosts hosts hosts hosts && touch hosts || touch hosts . code will execute only if the previous command executes successfully. but conditional execution only operates on the exit status of commands. 2. 4. or only if the previous command fails. If the last command to execute completed successfully. Option 4 is incorrect.Option 2 is correct. The ls hosts command will have an exit status of 0 if the host file exists. Option 3 is incorrect.

the system should send an e-mail to the root user. $ ls -l /var/log/mylog && cp /var/log/mylog /backup/mylog > MISSING CODE mail -s "Error" root < errmsg. the log file should be copied to a backup directory. command 1 || command 2 && command 3 Question Let's say that you want to create a command that will check for the existence of a log file. See if you can type an operator in the first blank space that will back up the log file if it exists.. If the copy operation fails. $ ls -l /var/log/mylog MISSING CODE cp /var/log/mylog /backup/mylog \ MISSING CODE mail -s "Error" root < errmsg.txt Answer You use the || operator to execute the mail root@localhost "copy operation failed" command if the copy operation returns a non-zero exit status. Grouping commands Conditional execution operations are based on the exit status value of a single command ± you can't have more than one command on either side of a conditional operator.txt Answer You use the && operator to run the cp /var/logs/mylog /backup/mylog command if the ls /var/logs/mylog command locates a log file. If the file exists. . Question See if you can complete the code shown here to send an e-mail to the root user if the copy operation fails. 3.

cat hosts) && ls Options: 1. round brackets (()) You can use round brackets (()) to create blocks of code that will execute in a subshell ( a new shell program spawned from the shell that you're running. You achieve this using grouping. You can group commands using the following two types of brackets: y y braces ({}) round brackets (()) braces ({}) You can use braces ({}) to create blocks of code that will execute in your current shell. any radical environment changes that take place during the running of a code block don't affect the shell you started with. rather than for each individual command that the block contains. The ls command will list the contents of the /etc directory 3. The code in parentheses executes within a subshell 2. but often you'll need to base conditional execution on the result of a series of commands. You can enclose a series of commands in brackets to create a code block. The code in parentheses is a comment Answer Code within parentheses is executed in a subshell. .This behavior is sufficient for simple tasks. As a result. The advantage of running commands in a subshell ( by grouping them using round brackets ( is that subshells have their own environment variables. Question Which statement about the line of code shown here is true? (cd /etc . The ls command will execute on condition that the cat hosts command is successful 4. The shell will treat a code block as if it were a single command ( it will return one exit status value for the entire block. cat hosts) && ls $ (cd /etc . This allows you to create far more complex commands and shell scripts.

You can set local environment variables within the subshell without effecting your main shell session. Question Identify the operators that allow you to group commands in code blocks. The . for instance. Option 4 is incorrect. The () symbols group commands into a code block that is executed in a subshell. the commands are executed in sequence. The [] symbols are used by the shell in pattern matching operations to specify character ranges. not as a code block. 3. Question . Option 2 is correct. Option 3 is incorrect. However. 4. You can include comments in shell scripts by preceding each line of comments with the # symbol. symbol is used to enter multiple commands on the same line. The {} symbols group commands into a single code block for execution in the current shell. Option 2 is incorrect. 2. Options: 1. This is useful if you want to avoid altering environment variables in your current shell. Option 1 is incorrect.Option 1 is correct. Code within parentheses is run as a separate process in a subshell. Answer You use the parentheses () and the braces {} operators to group commands in code blocks that return a single exit status. Option 3 is correct. The variable that stores the current working directory for the shell in which the ls command is executed is not affected by the command to move to the /etc directory in the subshell. Option 4 is incorrect. The execution of the ls command is conditional on the successful completion of the entire block of code within parentheses. [] {} () .

. ls mylog && echo "Found the log file" The command that changes the current working directory to /var/log is part of a code block enclosed in brackets (()). and plug them into each other using a pipe (|). At no point does any code change the directory to /usr/home ± either in the current shell or the subshell ± so this can't be the current directory. your current working directory will still be /home/gregl. you need to remove the braces. What do you think your current working directory will be when the code has finished executing? $ { cd /var/log . thereby changing the current directory. ls mylog } / && echo "Found the log file" Options: 1. You can separate commands using a semicolon (. It looks for a specific log file. and if the file exists a message displays. You use braces ({}) to specify that code execute in the current shell. Option 1 is incorrect. Option 3 is incorrect. continue them on new lines using a back slash (\).). as shown here: cd /var/log . /home/gregl 3. /usr/home Answer After the command runs. and two pipe characters (||) to specify that a command run only if a previous command failed. and round brackets (()) to specify that code execute in a subshell. The command that changes the directory to /var/logs runs in a subshell. As a result. /var/log 2. You can use conditional operators to specify that commands execute based on the exit status of other commands. To run the code in the current shell.Suppose that you're in /home/gregl and you need to execute the code shown here. it has no effect on the current shell you're in. You can group commands into code blocks to specify that the shell return one exit status for the entire block. Summary The shell's command line provides an interface between users and the UNIX kernel. so it will execute in a subshell. You use two ampersand characters (&&) to specify that a command run only if a previous command was successful.

Table of Contents
| Top of page | | Learning objective | | 1. Using the command line | | 2. Conditional execution | | 3. Grouping commands | | Summary |
Copyright © 2003 SkillSoft. All rights reserved. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

Redirection in UNIX
Learning objective

After completing this topic, you should be able to redirect standard input and output, and use file descriptors.

1. Using standard I/O redirection
Most UNIX commands behave as filters ± they can take input, process it in some way, and provide output. A shell usually sends this output to the screen, but you can redirect it to provide advanced functionality. A common example of redirection is the use of the pipe operator (|) to plug the output of one command directly into the input of another command. However, redirection most often involves writing to and reading from files. You can perform redirection with files by preceding a filename with one of the following operators: y y y greater than (>) less than (<) two greater than symbols (>>)

greater than (>)

You use the > operator with a filename to redirect the output of a command to a file. If the file doesn't exist, the shell will create it. If it exists, the shell will overwrite it. less than (<) You use the < operator with a filename to redirect standard input from a file. For example, when using the mail command to send e-mail, you can redirect input from a file you have previously prepared, rather than having to type your message at the shell prompt. two greater than symbols (>>) You use the >> operator with a filename to redirect the output of a command to a file, appending the new data if the file already exists. This is useful for creating log files. If you use a lot of file redirection in your scripts, it's quite easy to overwrite existing files accidentally. To prevent this, most shells implement the noclobber environment variable. When set, noclobber prevents file overwriting through redirection ± but not through the execution of commands such as cp or rm. You enable noclobber by typing set -o noclobber, as shown here. If you want to overwrite output files protected by noclobber, you can use the >| operator to do this. $ set -o noclobber $

Question
Let's say that you want to send e-mail to a user called vincep. You've used the vi editor to type the body of the e-mail, and you've saved it to a file called email.txt. See if you can complete the code shown here to redirect input from the email.txt file rather than from standard input.

$ mail ±s "Guess what" vincep@localhost MISSING CODE email.txt

Answer
You use the < operator to redirect input from a file rather than from standard input. You send the mail, and the shell reads the e-mail body from the text file you've specified.

$ mail ±s "Guess what" vincep@localhost < email.txt $

Question
Let's say you're using the man command to find out about the exec command. You'd like to dump the information to a file so that you can print it later. See if you can complete the command shown here to dump the output of the command to a file called exec.txt.

$ man exec MISSING CODE exec.txt

Answer
You use the > operator to redirect standard output to a file rather than to the screen. The shell dumps the output of the man exec command to a text file. Because you've redirected the output, you don't see it echoed to the screen. $ man exec > exec.txt $

Question
Match the redirection operators to the descriptions of their function. Options: 1. > 2. < 3. >> Targets: A. Used to append output from a command to a file B. Used to redirect output from a command to a file C. Used to specify a file as input for a command

Answer
You use the > operator to redirect the output from a command to a fle, the < operator to use a file as input for a command, and the >> operator to append the output from a command to an existing file.

You can use redirection to document your system by redirecting the output from commands to a file, as in this example, which records the network interfaces configured for a system: ifconfig ±a > network.txt Several UNIX commands accept files as input. For instance, you can redirect a text file called report.txt to the mail utility and send it to Fred with the following command: mail Fred < report.txt Appending command output to an existing file is useful for troubleshooting. Scheduling regular execution of the following command enables you to monitor which kernel modules are loaded on a Linux system: lsmod >> /var/modules.log

2. File descriptors
File descriptors are files ± usually with numeric filenames ( on disk that point to input/output (I/O) objects, such as the keyboard, the screen, or other files. You can think of them as placeholders. By using file descriptors, processes don't have to interact mechanically with the I/O objects that the descriptors represent ± the kernel handles these mechanics. Any running process can expect at least the three following default file descriptors to be available: y y y 0 Descriptor 0 is also known as standard input. It's normally mapped to the keyboard. Processes look to this descriptor for user input. 1 Descriptor 1 is also known as standard output. It's normally mapped to the screen, although when UNIX was created it was mapped to a printer. Processes write command output to this descriptor, and the output then appears on your screen. 2 Descriptor 2 is also known as standard error. It's normally mapped to the screen, but when UNIX was invented it was mapped to a dedicated printer. 0 1 2

and the messages then appear on your screen. using the following syntax ± where n is a file descriptor: y y y y y y <&n You use <&n to redirect standard input from another descriptor. set the noclobber variable. this will overwrite an existing file. n> filename You use n> with a filename to redirect a descriptor to the specified file. This will redirect to a file but. you could type <&2 to feed standard error into standard input. You can redirect file descriptors in a similar way to performing ordinary redirection. Processes can also create their own descriptors. overriding the noclobber variable if this has been set. you could type >&2 to send standard output into standard error. >&n You use >&n to redirect standard output to another descriptor. as with ordinary redirection. For example. <&n >&n n< filename n> filename n>> filename n>| filename Question Identify the true statements about performing descriptor redirection. using the set noclobber command. To change this default behavior and not have the file overwritten. usually for interacting with files. For example. this will append to an existing file. n>| filename You use n>| with a filename to redirect a descriptor to the specified file. n>> filename You use n>> with a filename to redirect a descriptor to the specified file. Options: . As with ordinary redirection.Processes write error messages to this descriptor. n< filename You use n< with a filename to redirect a descriptor from the specified file.

See if you can complete the first part of the code shown here to redirect standard output to a text file called output. you redirect standard error with 2>.txt MISSING CODE error.txt Answer You type > to redirect standard output to a file. Instead of the output going to the screen it can be redirected to a file using 1> Question Let's say that you want to use the find command to locate reports. Option 4 is correct. Use 1> to redirect standard output to a file Answer You use >&2 to redirect standard output to standard error.txt MISSING CODE error. $ find / -name "report*" MISSING CODE output. this option allows you to overwrite existing files with standard error.txt. This is useful for for printing error messages. In fact. and you redirect standard output to a file with 1>.1.txt. Option 1 is incorrect. Question See if you can complete the code shown here to redirect standard error to a file called error.txt . You use 2> to redirect standard error to a file 3. If your standard error is connected to a printer instead of the display. Option 3 is correct. $ find / report* 1> output. this would be a quick way of printing command output. Option 2 is correct. and you want to redirect both standard output and standard error to text files. You use 2>| to ensure that existing files aren't overwritten by redirected standard error 2. You use >&2 to redirect standard output to standard error 4.

the descriptor for standard output has a value of 1. Standard error is associated with file descriptor 2. Most programs use standard output to print usage messages or the results of commands. Standard output Answer The file descriptor for standard input has a value of 0. Typing commands with a keyboard is the most common way of interacting with the shell. You do this using a here document. 2 Targets: A. to record errors. Standard input is associated with file descriptor 0. and is usually mapped to the screen ± but it is sometimes useful to map it to a printer.Answer You type 2> to redirect standard error to a file. and is usually mapped to the keyboard. for convenience. you may want to pass multiple lines of input to a command. Question Match each standard file descriptor value to its name. Options: 1. Scripting with redirection Sometimes. 3. and the descriptor for standard error has a value of 2. Standard error B. Here documents make it possible to give batch input to a command ± to pass the command a list of things you want it to do. Standard output is usually mapped to the screen. 0 2. 1 3. Standard input C. You can use here documents using either of the following two syntax forms: .

$ telnet << END > open 190. until it reaches the word or character you've specified as a terminator.2. the shell executes the command and passes it the input you specify ( line by line. command <<. $ telnet << END > open 190.3 You know that the remote machine will require a username and password. $ telnet << END > The first thing that a telnet session needs is the address of the target machine ( 190. In this case.2. until it reaches the word or character you specified as a terminator.3 in this case. The trailing dash in the syntax causes all leading tabs in the subsequent input to be stripped. and the shell waits for further input. Then you press Enter. using the word END as a terminator.100. So you enter the full command to open a session to that machine and then press Enter.100. your username is "gregl" and your password is simply "password". the shell executes the command and passes it the input you specify ( line by line. Let's say that you want to automate a telnet session to e-mail yourself some data off a remote machine. You press Enter.3 > gregl password . so you type them on the next line. You begin by setting up the telnet command with a here document.terminator [input «] When you use the syntax command <<.terminator [input «] command << terminator [input «] When you use the syntax command << terminator [input].100. .terminator [input].2.y y command << terminator [input «] command <<.

3 > gregl password > mail ±s "remote userlogs" gregl@190. $ telnet << END > open 190.100. so you enter the commands you need to fetch the file you want. You press Enter after each command. Question Which statements about here documents are correct? Options: .operator to ensure that leading tabs are stripped out of here documents.100. you enter the terminator that you specified to begin with ( in this case.100.100. See if you can complete the code shown here to ensure that any leading tabs in the here document will be stripped out.The remote system should have logged you on by this point in the script. You also enter the quit command to end the telnet session.1 < /var/log/userlog quit To finish and execute the here document.2.2. $ ssh MISSING CODE Finish Answer You use the <<.2.2. using the word "END" as a terminator.3 gregl password mail ±s "remote userlogs" gregl@190. The shell executes the telnet command and feeds it the here document line by line. the word END ± and you press Enter. $ > > > > telnet << END open 190.1 < /var/log/userlog > quit > END Question Suppose that you're setting up a here document to run an ssh command.

The default file descriptors present in any shell environment include standard input (0).operator to strip leading tabs from lines in a here documents. can be automated using here documents Option 3 is correct. You can redirect file descriptors. Although END is frequently used as a terminator in here documents. Option 1 is correct. Using standard I/O redirection | | 2. The <<. Option 4 is incorrect. They are most commonly used for setting up scripts for interactive commands such as telnet.1. and standard error (2). accepting input and providing processed output. 4. such as telnet or ftp. and you can redirect command input from a file. 2. Here documents start with a command interpreter that loads a command to read and execute the rest of the shell script. Here documents are often used to automate interactive logins and the first line of a here document is always a command. Option 2 is correct. Summary Most UNIX commands behave as filters. standard output (1). File descriptors are numeric placeholders for input/output (I/O) objects. File descriptors | . Table of Contents | Top of page | | Learning objective | | 1. The terminator in here documents is END Answer You use the <<.operator allows you to strip leading tabs from a here document Here documents can be used to automate login processes The first line of a here document is always a command. Automatically stripping tabs from your here document allows you to improve its legibility. you can use any string as a terminator. Here documents provide a convenient way of sending batch input to a command. 3. You can redirect command output to a file. Most interactive command line programs.

Substitution and matching You can use filename substitution when entering commands to specify groups of files that you want to work with. You can specify limited lists of characters for filename substitution using square brackets ([]). 1. which it then passes to the command you're trying to execute. using one of the forms shown here: . Filename substitution involves using wildcard characters either on their own. For example. you should be able to use substitution and quoting to expand and match files and commands. if you specify w*. All other logos or trademarks are the property of their respective owners. Scripting with redirection | | Summary | Copyright © 2003 SkillSoft. the shell will return a list of every file in your current working directory with a name beginning with "w". if you specify file0?. All rights reserved. | Print | Contents | Close | Substitution and patterns in UNIX Learning objective After completing this topic. the shell might return a list containing file01 through file09 ± if these files existed. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries.| 3. question mark (?) You use the ? wildcard to match a single character. The shell resolves a wildcard to a list of files. For example. or with a pattern fragment. The wildcard characters that UNIX supports include y y asterisk (*) question mark (?) asterisk (*) You use the * wildcard to match a string of any length.

y y y [abc] [abc] [a-d] [a-ce-g] You use the form [abc] to perform substitution with any character that appears between the square brackets. and file07 ± if these files exist. the shell will return a list containing file01. [a-ce-g] You use the form [a-ce-g] to perform substitution with any character that appears in any of the ranges between the square brackets. the shell will return a list containing data_a. For example. file04. and data_c ± if these files exist.txt staffdata . which allows any type of string to follow the specified ranges. $ ls MISSING CODE Answer You type [a-z0-9]* or [0-9a-z]* to retrieve a list of all files that begin with a lowercase letter or a digit. the shell will return a list containing log1. and log8 ± if these files exist. if you specify file0[147]. For example. if you specify data_[a-c]. log6. [a-d] You use the form [a-d] to perform substitution with any character that appears in the range between the square brackets. the square brackets hold two ranges ± a to z and 0 to 9.txt report3. log7. $ ls [a-z0-9]* 120415_log report1. data_b. For example. Question See if you can complete the code shown here to retrieve a list of all the files in the current directory that begin with a lowercase letter or a digit. if you specify log[1-36-8]. In the filename substitution shown here. The brackets are followed by an asterisk (*). log2. You can include any number of ranges in this way. log3.

txt staffdata 120603_log report2. This enables you to write scripts with path references that any user can run. the code shown here lists all files in the current directory that don't end in a digit. ~user The shell resolves ~user to the path of a specific user's home directory.120603_log report2.txt searchdata $ You can perform reverse matching using the exclamation mark (!) character. you may need to refer to a user's home directory in a script. ~The shell resolves ~. For example.txt report3. You can refer to a user's home directory without knowing their username using the tilde (~) character. $ echo ~ /home/vincep $ You can use the tilde (~) character in substitution in the following forms: y y y y ~ The shell resolves a lone tilde to the value of the current user's $HOME environment variable.txt searchdata $ Occasionally. ~+ The shell resolves ~+ to the path of the current directory. $ ls ±l *[!0-9] 120415_log report1. ~ ~user ~~+ Question Which commands use the tilde (~) correctly? Options: .to the path of the previous directory you were working in.

4. Question Match each filename substitution format with its description. Substitutes for any single character D. [abc] [a-e] * ? Targets: A. while the ? matches any single character. Option 2 is incorrect. Substitutes for any character in a range C. so this command wouldn't work. You can also specify a range using the [a-e] format. Using the tilde command in this context changes the current directory to its previous value. cd cd cd cd ~ ~$HOME ~~Fred Answer These commands all use tilde substitution correctly Option 1 is correct.1. you use the [abc] format. 2. 2. 4. 3. In this case. Substitutes for zero or more characters Answer To substitute from a list of characters into a filename. the tilde command changes the current directory to the home directory of the user Fred. . Option 4 is correct. 3. The tilde substitutes for the $HOME variable. Option 3 is correct. Substitutes for any character in a list B. The * substitutes for any character zero or more times. In this circumstance. Options: 1. the command changes the directory to the home directory of the current user.

text. the shell executes the bracketed command first. $ ls ±l | grep MISSING CODE Answer The $(whoami) command returns your current username. . $(< filename) When you use $(< filename) as an argument for a command. The command ls file* will match and list any file with a filename that starts with file. text. In other words. including file123.b.[a-e] matches and lists every file named text with a suffix consisting of a period followed by a character in the range of letters from a to e. The command ls file? will match and list any file with a filename that starts with file and has one additional character. the shell reads the specified file and passes its entire contents to the command. which the grep command uses to filter the output of the ls ±l command. text. Command substitution Command substitution allows you to use the output of one command as an argument for another command.The command ls file[abc] would use filename substitution to match and list files named filea. Question See if you can complete the command shown here to display a list of files that belong to you. such as file1 or filea if they exist.a. without knowing what your username is. The command ls text.c. 2. text. text. and filec if they exist. It then passes this command's entire output to the unbracketed command. You can perform command substitution using the syntax y y $(command) $(< filename) $(command) When you use $(command) as an argument for another command. fileb.e will be listed.d.

Without the quotation marks. you can use backslash escaping to perform quoting. The code shown here displays an asterisk on the screen. you enclose them in quotes to prevent them from being interpreted. Which commands use a suitable alternative method for escaping special characters? Options: ." $ echo \'\*\' is a special character '*' is a special character $ Question If you need to pass special characters to a command in an argument. you must prevent the shell from interpreting it by quoting the character. This instructs the shell to pass the character literally to the command instead of trying to interpret it.1 vincep vincep -rw-r--r-. $ ls ±l | grep $(whoami) -rw-r--r-.1 vincep vincep 9880 9372 73234 247416 451008 Feb 11 15:40 120415_log Feb 11 15:41 120603_log Jan 8 09:22 report1. the command does not interpret that character. you place a backslash (\) immediately before a special character.txt When you include a special character such as a wildcard or a pipe as part of an argument for a command. the shell would have resolved the asterisk to a list of all the files in the current directory.1 vincep vincep -rw-r--r-. Instead. $ echo '*' * $ Instead of quote marks.1 vincep vincep -rw-r--r-.1 vincep vincep -rw-r--r-.The code shown here shows a list of the files in the current directory that you own.txt Jan 8 09:23 report2. "'*' is a special character.txt Jan 8 09:24 report3. The code shown here uses backslash escaping to print out the message. To do this. the shell resolves it and passes the output to the command as an argument. If you intend a command to use a special character as an argument. Backslash escaping is also useful for situations in which you need to pass an actual quote mark as an argument.

Option 3 is incorrect. and begin typing. The backslash prevents the $ from being interpreted as a special character. but you don't know what the user's username is. Option 2 is incorrect. 3. #!/usr/local/bin/ksh # Logon welcome script clear echo Welcome $(whoami) You add a line that uses command substitution to display the current date. echo $(< $)USER Answer You use the backslash to escape special characters. You begin the script by clearing the screen and you use command substitution to greet the user using the whoami command. go into insert mode.1. so $USER will be printed onscreen. #!/usr/local/bin/ksh # Logon welcome script clear echo Welcome $(whoami) echo The current date is $(date "+%d-%M-%Y") Question You want to display a list of all the reports in the user's home directory. echo \$USER 2. The $(command) syntax allows you to pass the output from a command as a parameter to another command. rather than the value of the $USER variable. You start the vi editor. . Option 1 is correct. and you're preparing a startup script that will run each time a user logs in. echo $($)USER 3. The $(< filename) syntax allows you to pass the contents of a file as a parameter to a command. Using substitution in a script Let's say that you're a system administrator.

#!/usr/local/bin/ksh # Logon welcome script clear echo Welcome $(whoami) echo The current date is $(date "+%d-%M-%Y") cd ~ ls -l | grep "MISSING CODE" Answer You type report* to have the command return all files that begin with "report". You test the script. Question You use the ls command to list the contents of the user's home directory. #!/usr/local/bin/ksh # Logon welcome script clear echo Welcome $(whoami) echo The current date is $(date "+%d-%M-%Y") MISSING CODE Answer You type cd ~ to navigate to a user's home directory without knowing the user's username. .Complete the code shown here to navigate to the user's home directory.txt -rw-r--r--1 vincep vincep 247416 Jan 8 09:23 report2. Welcome vincep The date is 26-08-2003 You have the following reports: -rw-r--r--1 vincep vincep 73235 Jan 8 09:22 report1.txt Question Identify the true statements about command substitution and wildcards. and it runs successfully. See if you can complete the code shown here to use the grep command to filter the output of the ls command to show only those files whose names begin with "report".

The shell resolves the argument command first and passes its output to the main command. The shell resolves a wildcard into a list of files that match specified search criteria. provides the following output: It is Fri Aug 18 11:25:55 BST 2003. You can use any combination of filename substitution and command substitution when you write shell scripts.Options: 1. The shell only performs filename substitution with wildcards. Command substitution allows you to use the output from a command as standard input for a second command 2. Similarly. Option 2 is correct. you can perform command substitution to use the output of one command as an argument for another command. Most shells let you use wildcards like asterisk (*) or a question mark (?) in filename substitution. for instance. The command echo It is $(date). Wild cards are used to perform filename substitution Answer You use command substitution to include the output from a command in an argument to another command and you perform filename substitution with wildcards. Redirecting standard output into the standard input of a command is performed using the UNIX pipe facility. Option 1 is incorrect. Command substitution allows you to use the output from a command as part of the argument for another command 3. Option 4 is correct. Table of Contents | Top of page | . Filename substitution provides a quick way of searching large directories for files conforming to a specific pattern. Option 3 is incorrect. The command echo It is $(dat*) will yield a "command not found" error message. Summary Filename substitution involves specifying groups of files to use as arguments for commands. Wild cards are used to perform command substitution 4.

Introduction There are hundreds of UNIX commands that you can execute at the shell prompt. Shells have their own built-in syntax that helps you to work more effectively with existing commands by allowing you to perform functions like plugging commands into each other and controlling the flow of execution.| Learning objective | | 1. Using substitution in a script | | Summary | Copyright © 2003 SkillSoft. the second command executes only if the first command fails. All rights reserved. Command substitution | | 3. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All other logos or trademarks are the property of their respective owners. Substitution and matching | | 2. Conditional execution operators || You use the double pipe operator in the form command1 || command2 In the above syntax. UNIX command syntax reference Abstract This article serves as a quick reference for the most commonly used shell scripting syntax. && You use the double ampersand operator in the form command1 && command2 .

If the specified file doesn't exist. If it does exist. I/O redirection operators > You use this operator to redirect command output to a file. rather than for each command in the block. the shell overwrites it with the command output even if the noclobber environment variable is set. >> You use this operator to redirect command output to a file.In the above syntax. If the file does exist. If the specified file doesn't exist. the shell creates the file. The shell returns one exit status value for the entire group. () You can enclose multiple statements in round brackets to create a code block. If the file doesn't exist. Command grouping operators {} You can enclose multiple statements in braces ({}) to create a code block. the shell creates the file. >| You use this operator to redirect command output to a file. This code block functions in the same way as a code block enclosed in braces. the shell overwrites it with the command output unless the noclobber environment variable is set. . the shell creates the file. but runs in a subshell. < You use this operator to redirect command input from a file. the shell appends the new data to the end of it. If the file does exist. the second command executes only if the first command executes successfully.

n> filename You use this operator with a filename to redirect descriptor n to the specified file. >&n You use this operator to redirect standard input to file descriptor n. n>| filename You use this operator with a filename to redirect descriptor n to the specified file. this will not overwrite an existing file. overriding the noclobber environment variable if it is set.File descriptor redirection operators <&n You use this operator to redirect standard input from file descriptor n. Filename substitution * You use the * wildcard to match a string of any length. n< filename You use this operator with a filename to redirect descriptor n from the specified file. ? You use the ? wildcard to match a single character. This will redirect to a file but. this will append to an existing file. . Unlike ordinary redirection. n>> filename You use this operator with a filename to redirect a descriptor to the specified file. unlike ordinary redirection.

[abc] . [a-c1-3] You use square brackets to match only characters that appear inside the specified set. For increased convenience. ~+ You use the ~+ operator to instruct the shell to return the full path of the current working directory. $(< filename) You use this form of command substitution to pass the entire contents of a file to a command as an argument. !pattern You use the ! operator with a pattern to perform a reverse match. [a-c] . ~username You use the ~ operator with a username to instruct the shell to return the full path of a specific user's home directory. Command substitution $(command) You use this form of command substitution to resolve a command and pass its output to another command as an argument. Tilde substitution ~ You use the ~ operator to instruct the shell to return the value of the $HOME variable. The shell returns only filenames that don't match the pattern. you can specify multiple ranges. ~- .

You use the ~. tilde. input/output (I/O) redirection. The shell will execute each command successively once you press Enter. and command substitution. This is useful for tasks that are likely to take a long time to complete. If you enter several commands on the same line. \ You use a backslash to allow you to press Enter and continue typing commands on a new line. They also allow you to perform filename. Table of Contents | Top of page | | Abstract | | Introduction | .operator to instruct the shell to return the full path of the previous working directory you used. Using a backlash in this way is known as backslash escaping. & You add a single ampersand at the end of a command to run that command as a background process. file descriptor redirection. and command grouping. but they also have built-in functions to help you use shells more effectively. Summary Shell programs can execute a wide range of UNIX commands. Most shells support standard operators for conditional execution. The shell will only begin executing your commands when you press Enter on a line that doesn't end in a backslash. you need to separate the commands with semicolons. Miscellaneous syntax .

SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft PLC in the United States and certain other countries. and e-mail that file to the root user. All rights reserved. output the search results to a file. All other logos or trademarks are the property of their respective owners.| Conditional execution operators | | Command grouping operators | | I/O redirection operators | | File descriptor redirection operators | | Filename substitution | | Command substitution | | Tilde substitution | | Miscellaneous syntax | | Summary | Copyright © 2003 SkillSoft PLC. Exercise overview In this exercise. you should be able to write a shell script that uses the shell's command execution and substitution capabilities. the script should display a message on the screen. | Print | Contents | Close | Using UNIX commands in a script Learning objective After completing this topic. If an error occurs. you're required to complete a script that will perform a search for certain types of files. This involves the following tasks: y y y using code blocks using substitution using redirection and conditional execution .

Round brackets (()) Square brackets ([]) Braces ({}) Less than and greater than signs (<>) Result You use braces ({}) to create a code block that will execute in the current shell. 3. 2. The commands should execute in the current shell. MISSING CODE MISSING CODE echo An error occurred during search operation Options: 1. such as: if [ $FEEDBACK = y ] then echo "proceed" else exit fi . You use round brackets to perform command substitution. mail -s "local reports" root MISSING CODE localreports . 4. Which type of brackets should you use to achieve this? MISSING CODE ls -l report MISSING CODE MISSING CODE localreports . Option 1 is incorrect.Task 1: Using code blocks Let's say that you're the root user and that you're editing a script in the vi editor. as in the variable assignment command shown here: DATE=$(date) Option 2 is incorrect. You use the square brackets to enclose conditional expressions. Step 1 of 1 You want the first two lines of the script to act as a distinct code block that returns one exit value for both commands.

The syntax for a function ± a sequence of code that is available to the shell into which it is read ± is: function_name() {commands} Option 4 is incorrect.mail -s "local reports" root MISSING CODE l ocalreports . } MISSING CODE echo An error occurred during search operation Result You specify report[0-9] with the ls command to list all files that begin with the word "report" and end in a number between 0 and 9. Task 2: Using substitution Step 1 of 1 Suppose that you want to use the ls command to search for all files that begin with the word "report" and end in a number between 0 and 9. { ls -l report[0-9] MISSING CODE localreports . { ls -l report MISSING CODE MISSING CODE localreports . They are also used as conditional operators (less-than and greater-than) within conditional expressions. } MISSING CODE echo An error occurred during search operation Result . mail -s "local reports" root MISSING CODE localreports . The <> special characters are used to perform redirection. Use substitution to complete the search criteria shown here. Type the symbol that will achieve this.Option 3 is correct. Task 3: Using redirection and conditionals Step 1 of 3 Suppose that you want to redirect the output of the ls command to a file named localreports.

{ ls -l report[0-9] > localreports . You've now successfully completed a script that will perform a search for specific files. a command block ( fails. { ls -l report[0-9] > localreports . output the search results to a file named localreports. you want to redirect the contents of a mail from the localreports file. mail -s "local reports" root MISSING CODE localreports . mail -s "local reports" root < localreports . } || echo An error occurred during search operation . { ls -l report[0-9] > localreports . Step 3 of 3 You want the last line of the script to execute only if the code block produces an error. } MISSING CODE echo An error occurred during search operation Result You use the double pipe symbol (||) to execute a command only if the preceding command ( or. It will also display an error message if the code fails. Step 2 of 3 In the second line of the script. } MISSING CODE echo An error occurred during search operation Result You use the less than symbol (<) to redirect input from a file. mail -s "local reports" root < localreports .You use the greater than symbol (>) to redirect output to a file. in this case. and e-mail the localreports file to the root user. Type the symbol that will do this. Type the correct symbol to do this.

| Print | Contents | Close | Working with UNIX variables Learning objective After completing this topic. You can turn local variables into global variables by exporting them using the export command.Table of Contents | Top of page | | Learning objective | | Exercise overview | | Task 1: Using code blocks | | Task 2: Using substitution | | Task 3: Using redirection and conditionals | Copyright © 2003 SkillSoft. including all its subshells and functions. All other logos or trademarks are the property of their respective owners. thus making it a global variable. All rights reserved. Global variables are available throughout the shell. you should be able to use variables in UNIX programming. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. Variables and data types Variables are named spaces used to store data. 1. Local variables are available only in the function or subshell in which they were created or declared. In this example. the code exports the local variable DEST from a subshell. $ export DEST $ .

float. and array variables. integer. you can define a variable as an integer or as a character string. which are floating-point decimal numbers arrays. You can only declare local variables in the Bash shell. All variables in the Bourne shell are global. TC shell variables can be either local or global. Korn shell variables can be either local or global. For example.Like most programming languages. This can change the way the shell uses the variables. which are whole numbers floats. For example. Bash shell . which are sequences of variables Each of the following popular UNIX shells supports variables and data types in different ways: y y y y Bourne shell Bash shell TC shell Korn shell Bourne shell The Bourne shell supports string variables only. Data types define the types of data contained in variables. UNIX shells allow you to define variables using data types. and array variables. Korn shell Like the TC shell. the shell performs faster arithmetic with integer variables. integer. the Korn shell supports string. The more advanced UNIX shells support four data types: y y y y strings. TC shell The TC shell supports string. Bash shell The Bash shell supports string and integer variables. which are sequences of alphanumeric characters integers. Options: 1. float. Question Match the UNIX shell type to its description.

Using variables The shell defines variables automatically when you assign a value to them for the first time.2. It's more likely to be deployed on proprietary UNIX systems than on open source systems. Bourne Shell 3. Supports string and integer variables B. while the Korn shell supports string. and array variables The Bash shell is based on the Bourne shell. Using typeset allows you to specify command-line options for the assignment operation. In this example. You can assign a value to a variable using the equal sign (=). Although you can export variables to make them global. $ typeset distance=4070 $ If you don't specify a value for a variable in an assignment statement. float. 2. it's useful for writing platform-independent shell scripts. $ distance=4070 $ You can use the typeset command to assign values to variables. In this example. integer. Supports string. they can only be declared locally. The Korn shell provides good support for variable typing and other useability features. the code assigns the value 4070 to a variable called distance. the Bash shell supports string and integer variables. although it has a limited feature set. float. . the shell assigns a null value to the variable. Supports string variables only Answer The Bourne shell only supports string variables. The Bourne shell is the most universally deployed shell and. integer. and array variables C. Korn Shell Targets: A. distance is set to null.

you use the print command and precede the variable name with a $ sign. departure . the code assigns the value of the distance variable to another variable called temp. 17h45 2. t 3. also using the dollar sign. $ print $distance 4070 $ You can assign the value of one variable to another variable. To view the value of a variable.$ distance= $ To refer to the value of a variable ± rather than to the variable itself ± you precede the variable name with a dollar sign ($). the code allows you to view the value of the distance variable. for example. In this example. $ temp=$distance $ To remove a variable entirely. In this example. the code removes the temp variable. In this example. you use the unset command. The print statement allows you to confirm that the variable no longer exists. $ unset temp $ print $temp $ Question What do you think is the output of the code shown here? $ t=17h45 $ departure=$t $ print $departure Options: 1.

this line of code displays a heading that includes special characters. Option 1 is correct. the shell displays it without processing the * and & characters. For example. Option 2 is incorrect. $ echo ***** Spain & Portugal ***** [1] 55412 ksh: Portugal: not found $ add_pkg_files Spain You can use the following kinds of quotes in UNIX shell scripts: y y y single quotes ('') double quotes ("") back quotes (``) single quotes ('') Single quotes ('') hide the meaning of all special characters. The value of the $departure variable is set to the value of the $t variable. not the character t. returning a list of files and an error message.Answer The output of the code is 17h45. you can enclose them in quotes. Quoting If you want to prevent the shell from processing spaces and special characters such as & and *. They allow you to use special characters ± including double and back quotes ± and spaces and newline characters in . It does not interpret $departure as the literal string departure. Option 3 is incorrect. 3. The command print $departure prints the value assigned to the departure variable ± in this case the value of the $t variable set in the first line of code. This variable is assigned a value of 17h45 in the first line of code. Because the character string is enclosed in quotes. the shell processes the special characters. The command departure = $t assigns the value of the $t variable to the $departure variable. $ echo '***** Spain & Portugal *****' ***** Spain & Portugal ***** $ If you omit the quotes.

the shell executes them and returns the value of their output. back quotes (``) Back quotes (``) are a method of command substitution that the Bourne shell uses. This means that command and variable substitution still take place in strings enclosed by double quotes. When you enclose a command in back quotes. Single quotes also prevent variable and command substitution because they hide the meaning of the $ character. $ Say you need to declare a variable that contains a full directory listing of the scripts directory. with the exception of back quotes (``) and the $ and \ characters. . $ pricetag='$50' $ item='trombone' $ priceline="The cost of a $item is $pricetag. double quotes ("") Double quotes ("") hide the meaning of special characters. You need to do this using single quotes to prevent the shell from treating the characters after the $ sign as a variable name. $ pricetag='$50' $ print $pricetag $50 $ Let's say that you want the shell to read the value of the item and pricetag variables and to include these values in the value of another variable called priceline. you need to use the ls command to obtain it." $ print $priceline The cost of a trombone is $50. and newline characters.strings. You can assign this value to a variable. Therefore. Using back quotes. Say you want to define a variable called pricetag and to specify that this variable must contain the string $50. You need to use double quotes so that you can combine the variable values with text. spaces. Because the listing needs to be up to date. The Korn shell retains them for compatibility with this shell. you can assign the output of the ls command to the drlist variable. you can use double quotes to combine variable values with a text string.

Question What do you think is the output of the code shown here? $ airline='PA' $ flightno="$airline 771" $ print $flightno Options: 1. Option 4 is correct. but it does not escape special characters. Placed at the end of a command. and `. Option 1 is incorrect.. but they can't be nested. Option 2 is correct. . Var=&$100 Var=\$100 Var="$100" Var='$100' Answer The backslash and single quotes prevent the $ symbol from being interpreted as a special character. airline 771 2. The backslash escapes all special characters. 3.$ drlist=`ls -a scripts` $ print $drlist . Single quotes prevent all special characters from being interpreted. So the expression \\ will be interpreted by the shell as \. except $. including itself. Double quotes prevent most special characters from being interpreted. add_pkg_files$ Question In which variable assignment statement is the $ symbol not interpreted as a special character? Options: 1. flightno 771 . 2. Option 3 is incorrect. 4. \. the ampersand causes the command to run as a background job.

The value of a variable can be one of several data types.3. Table of Contents | Top of page | | Learning objective | | 1. The second command substitutes the variable at the start of a string that consists of a space and the number 771. Summary Variables are named spaces for storing data. you precede the variable name with a dollar sign ($). Option 4 is incorrect. such as an integer or a character string. PA 771 4. PA771 Answer The output of the code is PA 771 because the double quotes allow variable substitution and the single quotes include the space character. Option 1 is incorrect. The first command assigns the value PA to the airline variable. Some shell environments support more data types than others. Single quotes and double quotes allow you to include special characters in strings. $airline refers to the variable set in the previous command line. so in the command flightno="$airline 771" . The special character $ symbol used to reference variables is retained within double quotes. not the flightno string. You can set the value of a variable using an assignment statement or the typeset command. The print command prints the flightno variable. Back quotes allow you to assign the output of a command to a variable. Double quotes allow you to create variables that include spaces because everything within the double quotes is interpreted as a single word by the shell. You can use quotes when assigning a value to a variable. Option 2 is incorrect. Variables and data types | . To access the value of a variable. Option 3 is correct. and assigns the resulting string to the flightno variable. You can unset them using the unset command. which is then printed.

-LZ) autoexport (-x) integer (-i) The integer attribute (-i) defines a variable as having the integer data type. defines a variable as an integer. An attribute is a setting that defines how a variable is represented. -L) right and left justify with zeroes (-RZ. -l) right and left justify (-R. The attributes you can set on a variable include y y y y y y integer (-i) float (-E. but it prevents you from assigning any non-integer value to the variable. 1. . All rights reserved. -F) The float attributes (-E and -F) define a variable as a floating-point decimal number.| 2. Defining variable attributes Any variable can have one or more attributes. All other logos or trademarks are the property of their respective owners. Using variables | | 3. or displayed. Quoting | | Summary | Copyright © 2003 SkillSoft. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. float (-E. for example. The integer attribute. and the left justify attribute formats a string variable so that it's left-justified. accessed. -F) lowercase and uppercase (-u. you should be able to describe and use script variables and parameters. | Print | Contents | Close | UNIX shell script variables Learning objective After completing this topic. This allows the shell to process integer values faster.

When you use the -F attribute. $ typeset -i dist $ In this example. -L) The right justify (-R) and left justify (-L) attributes allow you to format data. You use the typeset command to set and unset attributes. 196. right and left justify (-R.When you use the -E attribute. whereas variables with the -L attribute display at the left end of the specified field width. Variables with the -R attribute will display at the right end of the specified field width. -l) The uppercase attribute (-u) automatically converts any alphabetical characters in a variable's value into uppercase characters. The lowercase attribute (-l) converts any alphabetical characters in a variable's value into lowercase characters.543 and 2. right and left justify with zeroes (-RZ. lowercase and uppercase (-u. the code sets the integer attribute (-i) on the dist variable. -LZ) The right justify with zeroes (-RZ or -Z) attribute right-justifies a variable to a specified field width and fills the remainder of the field with leading zeroes. For example. you can specify the number of digits after the decimal point.1415 and 314. Paradoxically. you use a minus sign (-) to set an attribute and a plus sign (+) to unset it. $ typeset +i dist $ . The left justify with zeroes (-LZ) attribute left-justifies a variable to a specified field width and strips all leading zeroes. regardless of the position of the decimal point. the code unsets the integer attribute on the dist variable. In this example. This is useful if you want to ensure that the new value is available throughout the shell. 3.15 both have five digits. you can specify the number of digits in the number. For example. autoexport (-x) The autoexport (-x) attribute causes the shell to export a local variable whenever its value is set.160 both have three digits. You need to specify a field width when you set either of these attributes.

$ name=Novak $ typeset -u name $ print $name NOVAK $ You can use the readonly attribute (-r) to prevent any further changes to the value or attributes of a variable. 3. $ typeset -ux name $ Question At what stage do you think you can set attributes on a variable? Options: 1. or after assignment. if the value of name is Novak and you set the uppercase attribute (-u) on name. 4. . $ typeset -i dist=489 $ Attributes take precedence over a variable's current value. during. the code sets the uppercase attribute (-u) and the autoexport attribute (-x) on the name variable. 2. To assign an attribute and a value to a variable at the same time. However. For example. you can't set attributes on a variable that has been unset.You can set multiple attributes at the same time. its value becomes NOVAK. the code sets the integer attribute (-i) on the dist variable and assigns it the value 489. In this example. After you assign a value to it After you've unset it Before you assign a value to it While you assign a value to it Answer You can set attributes on a variable either before. In this example. you use the typeset command and specify the attribute before the value.

typeset-i typeset -l typeset -L typeset -x Targets: A. Options: 1. 3. For example. 4. rather than letters. You can use the typeset command to display a list of all shell variables that currently have a particular attribute. you cannot unset the readonly attribute on a variable once you've set it. 2. Ensures that the variable contains all lowercase characters B. the ±x attribute exports it.Unlike other attributes. the ±l attribute ensures all its characters are lowercase. and the ±L attribute ensures that the variable is left justified. $ typeset -i MAILCHECK=600 OPTIND=1 PPID=55394 RANDOM=22348 SECONDS=700 TMOUT=0 dist=489 $ Question Match the variable attribute to its function. Ensures that the variable is left justified D. Ensures that the variable is exported to subshells C. It enables you to make sure that numbers are assigned to the variables. Defines the variable as a whole number or its negative Answer The ±i attribute defines a variable as an integer. The ±i attribute is useful when you are using variables in calculations. this command displays a list of all variables with the integer attribute (-i). .

Environment variables are parameters that control the shell's behavior. The ±L attribute strips any leading spaces from a variable. including y y y y y y ? The ? parameter contains the exit status of the last command that the shell has executed. Examples of environment variables are y y y the SHELL variable. which defines a user's home directory the PATH variable. If it didn't execute successfully. the exit status is 0. Working with parameters Parameters are reserved variables that the shell uses. users can change the value of environment variables. which defines the search path for commands The shell has some special parameters that allow you to interact with current processes. If the command executed successfully.The ±l attribute is useful if you need to format the case of a variable consistently. ? ! $ PPID ERRNO . They allow you to control the behavior of the shell or to obtain information about current processes. They are global variables declared in each user's . you will need to add it to a shell configuration file. User-defined variables can't use the same names as the environment variables because the system has reserved these names. the exit status is non-zero. which is useful when you want to avoid errors in shell scripts in which variables are set interactively by the user.profile file. which defines a user's default shell the HOME variable. However if you want the variable to be available between logins. If you want to make a variable available to subshells. or to other users. you must export it using the ±x attribute. irrespective of its value. However. 2.

3. script. Positional parameters contain arguments that have been passed to a command. 2. 4. Question What do you think you can do to the values of special parameters such as ? and $? Options: 1. parameter 1 contains the first argument. so it may not be available on all systems. or unset them. set them. ERRNO The ERRNO parameter contains the error number returned by the most recent failed system call. Positional parameters are named according to the positions of the arguments they contain. PPID The PPID parameter contains the process ID (PID) of the current shell's parent shell process. $ The $ parameter contains the process ID (PID) of the current shell process. or function. . but you can't reassign them. In this command. They allow you to use these arguments in subsequent lines of a script.The . parameter 2 contains the second argument. This parameter is system-dependent. for example. Reassign them Set them Unset them View them Answer You can view the values of special parameters. the value of parameter 1 is a.parameter contains the shell options that are set on the current shell process. Parameter 0 contains the name of the command or function to which the arguments apply. the value of parameter 0 is ls. and the value of parameter 2 is the specified directory path. ! The ! parameter contains the process ID (PID) of the last background command or coprocess that the shell has executed. and so on.

$ ls -a /usr/home Positional parameters are particularly useful in functions. This example of a function searches the current directory for a specified file and displays the contents of the file one screen at a time. When you call the function and specify a filename as an argument, the filename is stored in the positional parameter $1. This allows the commands in the function to work with the filename. disf() { > ls -al | grep $1 > cat $1 | more > } $ You can call positional parameters only up to $9. If you want to use ten or more positional parameters, you need to enclose the identifying numbers in the parameter names in braces ({}). For example, the tenth positional parameter is ${10}. The expression $* returns the values of all current positional parameters, separated by spaces. The expression $# returns the number of current positional parameters.

Question
Identify the true statements regarding positional parameters. Options: 1. Although commands can take any number of arguments, you can only view nine positional parameters 2. Positional parameter 2 contains the second argument to be passed to a command 3. Positional parameter 0 always contains the value of a command or name of a function 4. You can use positional parameters within a function to manipulate its arguments

Answer
Positional parameter 0 refers to the command or function itself, while parameter 2 refers to the second argument passed to the command. One of the main uses of positional parameters is to call the arguments to a function from within the function.

Option 1 is incorrect. You can view positional parameter 10 or greater, but you must enclose it in braces, as in ${10}. Option 2 is correct. For the command cat file1 file2, the value of $2 is file2. Option 3 is correct. For the command cat file1 file2, the value of $0 is cat. Option 4 is correct. You can access an argument to the special_cat function as shown here: special_cat () {cat $1 | less}

Summary
You can set attributes that apply to a variable. Attributes can modify the way the shell processes a variable ± for example by defining it as an integer or floating-point decimal number. They can also modify the way the shell displays a variable value ± for example by specifying that it display as uppercase or left-justified characters. Parameters are predefined system variables. They include environment variables, which define characteristics of the shell environment, special parameters, which allow you to obtain data about current processes, and positional parameters, which allow you to work with arguments.

Table of Contents
| Top of page | | Learning objective | | 1. Defining variable attributes | | 2. Working with parameters | | Summary |
Copyright © 2003 SkillSoft. All rights reserved. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

Variable expansion and arrays in UNIX shell scripts
Learning objective

After completing this topic, you should be able to explain variable expansion and use array variables.

1. Variable expansion
Variable expansion allows you to access the values of variables. The simplest form of variable expansion involves referring to the value of a variable directly. To do this, you place a dollar sign ($) in front of a variable name. Other forms of expansion allow you, for example, to refer to portions of a variable's value or to the length of a variable's value, or to specify default or alternative variable values. You can use braces ({}) to delimit the value of a variable from any characters following the variable name. This allows you to use the variable name in assignment statements that change the value of the variable. In this example, the variable en contains the name "EasyNomad." Using braces, you can change its value to "EasyNomadTravel" by invoking its original value. $ en=EasyNomad $ en=${en}Travel $ print $en EasyNomadTravel $ If you precede a variable name with a hash sign (#), you can determine the length of its value ± the number of characters it contains. In this example, the output of the command specifies that the value of the en variable contains 15 characters. $ print ${#en} 15 $ The following variable expansion formats allow you to work with default and alternative values: y y y y y ${variable:-word} ${variable:=word} ${variable:+word} ${variable:?word} ${variable:?}

${variable:-word}

The ${variable:-word} syntax returns the value of the variable if it's set and non-null. If it's not set or if it's set to null, the expression returns the text string word. For example, ${name:-Name not found} returns the value of the name variable. If name is null or not set, it displays the message "Name not found". ${variable:=word} The ${variable:=word} syntax returns the value of the variable if it's set and non-null. If it's not set or if it's set to null, the expression assigns the text string word to the variable and then returns the variable's new value. For example, ${name:=anonymous} returns the value of the name variable. If name is null or not set, it assigns the value "anonymous" to name and returns the value "anonymous". ${variable:+word} The ${variable:+word} syntax returns the text string word if the variable is set and non-null. If it's not set or if it's set to null, the expression returns nothing. For example, ${name:+Name already exists} returns the string "Name already exists" if the value of the name variable is set and non-null. If name is null or not set, nothing is displayed. ${variable:?word} The ${variable:?word} syntax returns the value of the variable if it's set and non-null. If it's not set or if it's set to null, the expression returns the text string word and the shell terminates. You can use this format to ensure that essential variables are set before a script executes further. ${variable:?} The ${variable:?} syntax returns the value of the variable if it's set and non-null. Otherwise, the expression returns the default error message "parameter null or not set" and the shell terminates. The following variable expansion formats allow you to extract substrings from variable values: y y y y y y ${variable:start} ${variable:start:length} ${variable#pattern} ${variable##pattern} ${variable%pattern} ${variable%%pattern}

${variable:start}

For example. if the value of the tour variable is "landing ground on island". For example. say the value of the tour variable is "landing ground on island". the expression ${tour%*land} finds the last and shortest instance of land* and removes it. It therefore returns "ing ground on island". beginning at the left of the variable's value. It then removes this substring and returns the remainder of the value. beginning at the right of the variable's value. if the value of the tour variable is " landing ground on island". the expression ${en:4} returns "Nomad". For example. if the value of the en variable is EasyNomad. ${variable%pattern} The ${variable%pattern} syntax finds the shortest substring that matches pattern. ${variable##pattern} The ${variable##pattern} syntax finds the longest substring that matches pattern. if the value of the en variable is EasyNomad. . For example. It then removes this substring and returns the remainder of the value. It then removes this substring and returns the remainder of the value. ${variable#pattern} The ${variable#pattern} syntax finds the shortest substring that matches pattern. from the character position specified by the integer start to the end of the value.The ${variable:start} syntax returns part of the value of a variable. the expression ${tour##land*} finds the first and longest instance of land*. It then removes this substring and returns the remainder of the value. beginning at the right of the variable's value. ${variable%%pattern} The ${variable%%pattern} syntax finds the longest substring that matches pattern. It removes this and returns nothing. the expression ${en:4:3} returns "Nom". which is the entire string. The selected substring begins at the character position specified by the integer start and contains as many characters as specified by length. ${variable:start:length} The ${variable:start:length} syntax returns part of the value of a variable. For example. The expression ${tour#land*} finds the first and shortest instance of land* and removes it. beginning at the left of the variable's value. It therefore returns "landing ground on is".

the expression ${heading/flight/tour} returns the string "Last-minute tours and cut-price flights". ${variable#pattern1/pattern2} The ${variable#pattern1/pattern2} syntax replaces the first instance of pattern1 in a variable's value with pattern2 if the value begins with pattern1. if the variable col3 contains the string "Cost of flight". For example.For example. say the variable heading contains the string "Last-minute flights and cutprice flights". Removing this. ${variable//pattern1/pattern2} The ${variable//pattern1/pattern2} syntax replaces all instances of pattern1 in a variable's value with pattern2 and returns the result. For example. which is the entire string. the expression ${col3%flight/cruise} returns the string "Cost of cruise". it returns nothing. if the variable heading contains the string "Last-minute flights and cut-price flights". the expression ${col3#Cost/Price} returns the string "Price of flight". say the variable col3 contains the string "Cost of flight. ${variable%pattern1/pattern2} The ${variable#pattern1/pattern2} syntax replaces the last instance of pattern1 in a variable's value with pattern2 if the value ends with pattern1." In this case. The following variable expansion formats allow you to find and replace substrings in variable values: y y y y ${variable/pattern1/pattern2} ${variable//pattern1/pattern2} ${variable#pattern1/pattern2} ${variable%pattern1/pattern2} ${variable/pattern1/pattern2} ${variable/pattern1/pattern2} replaces the first instance of pattern1 in a variable's value with pattern2 and returns the result. For example. In this case. if the value of the tour variable is "landing ground on island". the expression ${heading//flight/tour} returns the string "Last-minute tours and cut-price tours". Question You have set the value of the file variable to file1. the expression ${tour%%*land} finds the last and longest instance of land*. . For example.

and return just part of a variable. The command en=${file}2 changes the value of the variable to file12 The command echo ${#file} returns the integer 5 The command echo ${file:4} returns the integer 1 The command echo ${file:?} returns a null value and exits the shell Answer Variable expansion allows you to reuse the current value of a variable when assigning a new value. Options: 1. or perform an arithmetic operation on it if it is an integer to create a new value. 2. you can display a custom error message if a variable is not set. Option 2 is correct. and replace a substring in the value of a variable with another substring. In this case the variable has been assigned a five-character string. 3. Question What do you think you can do using variable expansion formats? Options: 1. so only the last character is returned. . 4. return the number of characters in a variable. The number in this syntax identifies where the returned string starts. When using braces to expand a variable. You can expand the current value of a variable and include it as part of a new string. preceding the variable name with a # symbol returns the number of characters in a variable. 4. Option 4 is incorrect. not the string or integer itself. 3. Display a custom error message if a variable is not set Extract a substring from the value of a variable Replace a substring in the value of a variable with another substring Replace the value of one variable with the value of another variable Answer Using variable expansion formats. or has been assigned a null value. Option 1 is correct. This only happens if the file variable has either not been assigned.Select the statements that correctly describe variable expansion of the file variable. 2. extract a substring from the value of a variable. Option 3 is correct.

Question How do you think you create an array variable? Options: 1. 2. the subscript of the first element is [0]. . You simply assign the variable as shown: newvar=$file 2. or has a null value. Arrays Arrays are variables that can contain multiple values. This subscript takes the form of a number enclosed in square brackets. If the file variable is not set. Variable expansion isn't used for this. that value becomes the value of the array's first element. stored as a sequence of elements. Therefore. and so on. 4. The name of an array variable denotes the entire array. If the file variable has been assigned the value file1. you can replace the 1 with a 2 using the command: echo ${file/1/2} Option 4 is incorrect. 3.Option 1 is correct. If the file variable has been assigned the value file1. If a variable already has an existing value when you convert it into an array. You refer to an individual element in an array using a subscript that identifies its position in the sequence of elements in the array. the subscript of the second element is [1]. you can return just the 1 using the command: echo ${file:4} Option 3 is correct. this command will output the message "File not found": echo ${file:-File not found} Option 2 is correct. Numbering begins at zero. By applying the array attribute to an existing variable By assigning a value to one of its elements By assigning a value to the array By creating an ordinary variable with the typeset command using the array attribute ±A Answer You create an array variable by assigning a value to one of its elements.

${!array[*]:n:x} . the code assigns the value "January" to the mth variable.In this example. ${!array[*]} ${!array[*]} lists all initialized subscript values of an array. Assuming that the value of count is 3 and the fourth element in the array is "wooden giraffe". The next line of code displays the element whose subscript is contained in the variable count." $ mth=January $ mth[1]=February $ print ${mth[0]} January $ If you use arithmetic expressions or variables in the subscript of an array element. The value of mth[0] is still "January. In this example. beginning with the subscript n. For example. which lists souvenirs for sale. the shell evaluates the expressions or variables and then references the array. ${!items[*]:5} lists all elements of the items array from the sixth element onwards. ${!array[*]:n} The ${!array[*]:n} syntax lists all array elements. the resulting output is "wooden giraffe. the code assigns a value to element 4 + 9 of the items array." $ items[4+9]="safari hat" $ print ${items[$count]} wooden giraffe $ The following variable expansion formats allow you to work with array variables: y y y y y y ${array[*]} ${!array[*]} ${!array[*]:n} ${!array[*]:n:x} ${#array[*]} ${#array[n]} ${array[*]} ${array[*]} lists all elements of an array. thereby making it an array. It then assigns the value "February" to the mth[1] element.

The ${!array[*]:n:x} syntax lists x array elements. "$1+1 . For example. $ > > > > $ get_item() { print "Item no. $1" Then you print the length of the specified element. ${#array[n]} The ${#array[n]} syntax returns the length of the array element specified by the subscript [n]. $ get_item() { > You begin by printing the subscript specified in the argument. $1" print "Length ${#items[$1]}" print ${items[$1]} } When you call the get_item function for element 2. in the items array. and eighth elements of the items array. as well as the number and length of this element. You decide to name the function get_item. You do this using a positional parameter. beginning with the subscript n. $ get_item() { > print "Item no. $ get_item() { > print "Item no. $1" > print "Length ${#items[$1]}" Finally. the data for the third element of the items array displays. ${!items[*]:5:3} lists the sixth. The items array is an existing array that lists souvenirs for sale. $ get_item() { > print "Item no. you print the value of the specified element. ${#array[*]} The ${#array[*]} syntax returns the number of elements in an array. Let's say that you want to write a function that accepts an element number as an argument and displays a specified element. seventh. using the appropriate array variable expansion format.

Options: 1. You use the ! metacharacter to reference the subscript values in an array.> print "Length "${#items[$1]} > print ${items[$1]} > } $ get_item 2 Item no. . You use an element's subscript to reference the element. ${!var[*]} returns every initialised subscript. A subscript consisting of a number equal to the total number of elements in the array is initialized whenever you add an element. Returns all the elements of the array B. Returns the number of elements in the array Answer The statement ${var[*]} returns all the elements in the array. Returns all the initialized subscript values of the array C. ${!var[*]} 3. the variable var is an array. ${var[*]} 2. ${#var[*]} Targets: A. Match the expansion statements for the var variable to their corresponding functions. The value returned when you use the # metacharacter will be equivalent to the value of the last subscript to be initialized for the array. and ${#var[*]} returns the number of elements in an array. You use it to reference every element in an array. The * metacharacter is used as a wildcard. 2 Length 14 leopard poster $ Question In this question.

Performing simple arithmetic You can incorporate arithmetical and logical expressions in UNIX command-line statements and shell scripts. you can simply assign an integer value to it. You assign and access the elements of an array using a subscript in square brackets. Table of Contents | Top of page | | Learning objective | | 1. To declare an integer variable. | Print | Contents | Close | UNIX arithmetic operators and precedence Learning objective After completing this topic. Variable expansion | | 2. You can store multiple values in a variable by turning it into an array. Arrays | | Summary | Copyright © 2003 SkillSoft. Using variable expansion formats. However. The shell evaluates these expressions and substitutes the results for the expressions themselves. . the shell works with positive integers only.Summary The process of variable expansion allows you to work with the values of variables. you should be able to use arithmetic operators in shell scripts. All other logos or trademarks are the property of their respective owners. you can extract or replace part of a variable's value. the code itemID=5 declares the integer variable itemID. You can also provide default and alternative values. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All rights reserved. 1. For example.

$ integer itemID=5 Alternatively. you can declare variables explicitly using the typeset command with the -i option to set the integer attribute on them. the expr command was used to evaluate expressions. In early versions of UNIX. which improves performance and allows type checking. $ typeset -i itemID=5 Integer variables in the UNIX shell don't need to use the base-10 decimal system. In this example. In this example. the code assigns the hexadecimal value of B1F7 to the position variable. This bypasses the process of variable expansion. the code assigns the binary value 1101 to the nibble variable. The let command doesn't require that you use a dollar sign ($) when referring to a variable's value. $ let "i=i + 1" . To do this. you need to enclose it in quotes. $ nibble=2#1101 You can specify a base number after the -i option of the typeset command. This example shows the variable i being incremented by 1. which makes it up to 60 times faster than the expr command. although this is the default. you use a hash symbol (#) between the base and the value. To specify a base number other than 10 for an integer variable.However. $ typeset -i16 position=B1F7 Note You can use any base between 2 and 36. you can also declare an integer variable explicitly. $ i = `expr $i + 1` More recent versions of UNIX support the let command. you use the integer command. $ let i=i+1 If you include spaces or special characters in an arithmetical expression.

((18%8)) evaluates to 2. . 4. you can use double brackets as shown here. $ ((rem = 18 % 8)) $ print $rem 4 $ You can assign negative values to variables by placing a minus sign (-) immediately in front of the value. 36 72 120 144 Answer The expression 12 * (48 / 6 + 2) evaluates to 120. you need to use the print . because 18 divided by 8 is 2.As an alternative to using the let command to evaluate expressions. because otherwise the print command interprets the minus sign in a variable value as an argument. The UNIX shell supports a modulo operator (%). 2. it follows the conventional order of precedence for arithmetical operators. which returns the remainder that results from the division of one expression by another. Question What do you think is the result value of the following expression? 12 * (48 / 6 + 2) Options: 1. 3. leaving a remainder of 2. However. unless you use brackets to override this precedence. For example.command to display negative values. Multiplication (*) and division (/) operators take precedence over addition (+) and subtraction (-) operators. $ ((i=i + 1)) When the shell evaluates an arithmetical expression. The shell treats the code in the brackets as an arithmetical expression and evaluates it.

you use the typeset ± i option. Logical and bitwise operations The UNIX shell supports logical operators that perform Boolean logic operations on expressions. You can declare integers that aren't base 10 You can use binary numbers as integers You use the typeset option to explicitly declare an integer variable You need to explicitly declare integer variables Answer You can use the typeset option to explicitly declare integer variables that aren't base 10. 3. Option 4 is incorrect. Option 1 is correct. To explicitly declare an integer variable. 2. Binary numbers are base 2. 4. and you can use variables with base 2 integers as values. Options: 1. such as variables containing binary numbers. Option 3 is correct. You can declare hexadecimal integers like this: Variable=16#b6 Option 2 is correct.$num -9 $ Question Identify the true statements concerning declaring integer variables. which are base 2. The logical operators that the shell supports are y y y logical AND (&&) logical OR (||) logical negation (!) . 2. You can make a variable an integer variable by simply assigning it an integer value. Integer variables can use any base between 2 and 36.$ let "num = -9" $ print . although the default is 10.

it returns a 1. It returns a 0 if either of the bits is 0. bitwise XOR (^) . For example. logical OR (||) The || operator compares two expressions logically and evaluates the entire expression to zero if either of them are true. This is chiefly useful for working with binary numbers. and vice versa. the entire expression evaluates to one. The bitwise operators are y y y y bitwise AND (&) bitwise OR (|) bitwise XOR (^) bitwise negation (~) bitwise AND (&) The & operator compares two expressions bit by bit. ((2#1101 & 2#1001)) evaluates to 2#1001. the ! operator changes it to one. If both are true or evaluate to zero. Whereas logical operators compare and manipulate entire expressions.logical AND (&&) The && operator compares two expressions logically. bitwise operators perform Boolean logic on individual bits. The entire expression evaluates to one only if both expressions are false. The UNIX shell supports several bitwise operators. If either of the bits is 1. logical negation (!) The ! operator evaluates an expression and then reverses it logically. it returns a 1. It returns a 0 only if both bits are 0. If an expression evaluates to zero. For example. bitwise OR (|) The | operator compares two expressions bit by bit. the entire expression evaluates to zero. ((2#1101 | 2#1001)) evaluates to 2#1101. If both bits are 1. If either or both are false or evaluate to one.

These act on binary number values. 3. Option 1 is correct. Question Which operator performs bitwise reverses on the value of each bit in a binary expression? Options: 1. ((2#1001 >> 1)) evaluates to 2#100. the result will be 1110. Bits at the right end of the original values are lost. ~ & ^ | Answer The ~ operator performs bitwise negation on the value of each bit in a binary expression. For example. The UNIX shell supports bit shift operators. For example. ((2#1001 << 1)) evaluates to 2#10010 and ((2#11 << 2)) evaluates to 2#1100. shifting their bits either to the left or to the right by a specified number of places. If you perform bitwise negation on the base2 integer 10001. If one of the bits is a 1 and the other is a 0. For example. It returns a 0 if both bits are 1 or if both bits are 0. it returns a 1. For example. ((~ 2#1001)) evaluates to 2#110. 4. The left shift operator (<<) shifts bits to the left. 2. The right shift operator (>>) shifts bits to the right.The ^ operator compares two expressions bit by bit. The newly created bits on the right are zeros. ((2#1101 ^ 2#1001)) evaluates to 2#100. . bitwise negation (~) The ~ operator acts on one expression to turn all zeros into ones and vice versa.

The first statement compares the two binary numbers. yielding a result of 1011. 4.$y Options: 1. This is not valid output for a binary integer.Option 2 is incorrect. 2. Where both bits are set. You use the ^ symbol to perform a bitwise XOR on two binary expressions. You use the & symbol to perform a bitwise AND on two binary expressions. This would be the result if the first statement were a bitwise XOR. The first statement sets x to 2#0100 and the second statement performs bitwise negation on this value. Option 4 is incorrect. If it were. the leading zero would be stripped. 3. 0100 11 0 100 Answer The output of this code is 2#1011. yielding a result of 1111. Question What do you think is the output of the following piece of code? ((x = 2#1101 & 2#110)) ((y = ~x)) print . Where one bit isn't. Option 3 is incorrect. bit by bit. the returned bit is also not set. 3. the returned bit is also set. unsetting set bits and setting unset bits. You use the | symbol to perform a bitwise OR on two binary expressions. Option 3 is incorrect. Option 2 is correct. This would be the result if the first statement were a bitwise OR. Option 1 is incorrect. The second statement performs bitwise negation. Option 4 is incorrect. Additional operators .

less than or equal to (<=) The <= operator returns 1 (false) if the expression before it evaluates to a higher value than the expression after it. it returns a 0 (true). The comparative operators that the UNIX shell supports are y y y y y y less than (<) greater than(>) less than or equal to (<=) greater than or equal to (>=) equal to (==) not equal to (!=) less than (<) The < operator returns 0 (true) if the expression before it evaluates to a lower value than the expression after it. . equal to (==) The == operator returns 0 (true) if the expression before it evaluates to the same value as the expression after it. it returns a 1 (false). greater than(>) The > operator returns 0 (true) if the expression before it evaluates to a higher value than the expression after it. If not. For example. Otherwise. it returns a0 (true). Otherwise. Otherwise. not equal to (!=) The != operator returns 1 (false) if the expression before it evaluates to the same value as the expression after it. it returns a 1 (false).The UNIX shell supports a range of comparative operators that compare the values of two expressions. The UNIX shell simplifies this task with increment and decrement operators. it returns a 1 (false). Otherwise. Otherwise. it returns a 0 (true). greater than or equal to (>=) The >= operator returns 1 (false) if the expression before it evaluates to a lower value than the expression after it. The increment operator (+=) sets a variable to a new value that's equal to its previous value plus any number you specify after the operator. One of the most common arithmetic tasks consists of incrementing or decrementing a variable. These are useful when you need to set conditions for conditional statements. ((count+=1)) increments the count variable by 1.

respectively. a value of 1 is returned. The first line evaluates a conditional expression and returns a value of 0 or 1. Option 3 is correct. The decrement operator (-=) sets a variable to a new value that's equal to its previous value minus any number you specify after the operator. Option 1 is incorrect. so the value that is assigned to $x is 1. For example. The next expression increments the value of $x by 2. and when $x is printed it has a value of 3.Question What do you think is the output of the following piece of code? ((417 <= 28)) x=$? ((x += 2)) echo $x Options: 1. y=2 Which statements will not yield an error to this command? Options: . The $? variable is assigned the exit status of the previous command. and the print statement prints the new value of $x ± 3 ± to the screen. depending upon whether the expression evaluates as true or false. ((remainder-=1)) decrements the remainder variable by 1. the previous command is the conditional expression that evaluates as false. Option 2 is incorrect. The first line does not return a value of 417. 2 3. When a conditional expression evaluates as false. Question You have issued the following command to assign values to variables: x=4 . 419 2. 3 Answer The output from this code is 3. So the value of $x that is incremented by 2 is 1. In this case.

so this statement would result in an error. The x variable is greater than variable y. Option 1 is correct. $x >= $y. Table of Contents | Top of page | | Learning objective | | 1. division. so this statement is correct. Option 3 is incorrect. The UNIX shell also supports comparative operators that compare the values of two expressions. The UNIX shell supports logical and bitwise operators that perform Boolean logic on entire expressions or on individual bits of binary numbers. Option 2 is correct. 3. so the statement is correct. The == operators means "is equal to". and modulo operators. subtraction. The != operator means "is not equal to".1. 4. multiplication. making it larger than the x variable. Option 4 is correct. $x >= $y $x < $y+=4 $x == $y $x != $y Answer $x < $y+=4. The +=4 operator increments the y variable by 4. The basic arithmetical operators include addition. Performing simple arithmetic | | 2. Summary You can evaluate arithmetical expressions using the let command or the ((«)) construct. The >= operator means that the value on the left is equal to or greater than the value on the right of the operator. These follow the conventional precedence order ± with multiplication and division taking precedence over addition and subtraction ± unless parentheses override this convention. 2. Logical and bitwise operations | . and $x != $y all use comparative and increment operators correctly to construct valid statements.

All other logos or trademarks are the property of their respective owners. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. This involves the following tasks: y y creating and assigning variables performing arithmetical calculations Let's say that you're working for the EasyNomad travel company and you're required to write a script that calculates the amount of commission that agents earn on each package tour they sell. Exercise overview In this exercise. | Print | Contents | Close | Using calculations in a UNIX script Learning objective After completing this learning object. Type the command that declares variables explicitly and the attribute that specifies a variable to be an integer.| 3. #!/usr/local/bin/ksh MISSING CODE . All rights reserved. Step 1 of 2 The commission percentage will be stored as a positive integer. you're required to write a piece of code that performs calculations using variables. Additional operators | | Summary | Copyright © 2003 SkillSoft. you should be able to use variables and arithmetic in a shell script. you need a variable to store the commission percentage that agents receive and another variable to store the amount received. Task 1: Assigning variables For the commission script.

Complete the line of code that creates a variable called commrate and assigns the value of 10 to it. Step 1 of 3 Type the command that evaluates arithmetical expressions. You repeat the same task to create the amount variable.Result The typeset -i command declares integer variables explicitly. #!/usr/local/bin/ksh typeset -i commrate=10 typeset -i amount MISSING CODE Result The let command evaluates arithmetical expressions. #!/usr/local/bin/ksh typeset -i MISSING CODE Result You type commrate=10 to create and set the variable. You don't assign a value to amount yet because it still needs to be calculated. Step 2 of 3 . #!/usr/local/bin/ksh typeset -i commrate=10 typeset -i amount Task 2: Performing calculations The script you are writing needs to accept the value of a tour package that an agent sells as its first argument. Step 2 of 2 Let's say that agents receive a commission of 10 percent.

Type the code that assigns the value of the script's first argument to the amount variable. The script is now complete. #!/usr/local/bin/ksh typeset -i commrate=10 typeset -i amount let MISSING CODE Result You type amount=$1 to assign the value of the script's first argument to the amount variable. Step 3 of 3 Type the arithmetical expression that applies the commission percentage to the value of the amount variable. #!/usr/local/bin/ksh typeset -i commrate=10 typeset -i amount let amount=$1 let amount=amount*commrate/100 print amount Table of Contents | Top of page | | Learning objective | | Exercise overview | . You add a print statement to output the value of the amount variable. #!/usr/local/bin/ksh typeset -i commrate=10 typeset -i amount let amount=$1 let amount= MISSING CODE Result You type amount*commrate/100 to apply the commission percentage to the value of the amount variable.

and footnotes when displaying or printing documents. The earliest UNIX text formatter was runoff. and track documents and memos in the AT&T/Bell Telephone Company in the late 1960s. All other logos or trademarks are the property of their respective owners. It was later rewritten in C. You can run this formatter using the command roff. All rights reserved. binary output is not legible to human beings. Each command to a line editor specified a line number. Plain text Although computer processors act on binary data. which was named after print runs in the publishing industry. Text formatting To improve the readability of text created in a text editor on UNIX systems ± and to print this text. The text editors at this time were referred to as line editors because they required all changes to a file to be made on a line-by-line basis. | Print | Contents | UNIX text tools Abstract This article discusses the history of UNIX text and format processing tools. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. Early text processing One of the original purposes of UNIX was to develop. . Text formatters allow you to specify features such as fonts. although it retained the same functionality.| Task 1: Assigning variables | | Task 2: Performing calculations | Copyright © 2003 SkillSoft. next runoff (nroff) and typesetting runoff (troff) have been developed to provide additional features and greater flexibility. margins. spacing. and the changes to be applied to that line. you need a separate program to format it. paragraphs. maintain. The original standard UNIX linemode text editor ± named "ed" ± was first compiled in assembly language. Since runoff. Output needs to be in plain text for processed data to be accessible to both the computer and its human operator.

as well as support for indexing. In this case. line drawing. and TeX have also been developed. mathematical equations. Scribe. You can start up a UNIX shell from inside Emacs. cross-referencing. and TeX. there is a full-featured Lisp interpreter written in C. you receive a UNIX prompt inside the current Emacs window. LaTeX is a set of macros based on TeX macros that facilitates the structuring of large documents. You can also open more than one document at a time and use Emacs windows to move between documents. it provides Greek symbols. and tables. This built-in programming language allows you to customize and extend Emacs. You can then run commands ± including compile commands ± as you would outside of Emacs and save the shell output to a file. page layout. multicolumn printing.Other text formatters such as SCRIPT for IBM mainframes. Digital Standard Runoff (DSR). At the core of Emacs. It is especially suited to material with a high mathematical content. For example. Shell programming tools In addition to the runoff text formatter. there are a number of text tools that system administrators commonly use in shell programming. This allows you to navigate through the document to edit pieces of text at random. books. Emacs is a visual editor in that it displays a representation of an entire document on screen. diacriticals. TeX provides fonts and font sizes. and theses. diagrams and boxes. TeX and LaTeX TeX is a text processor used mainly in scientific and mathematical environments to produce papers. The most commonly used tools are y y y the sed utility the awk language the PERL language sed . Emacs. and bibliography macros. footnotes. mathematical characters. Emacs The Emacs text editor was written mostly in the programming language Lisp. and alternative character sets. It provides automated section and chapter.

Weinberger. to format text. PERL also includes awk. or you can create a command file containing awk statements. the awk command will remove the second field from each line in a file called profile. runoff was subsequently developed to improve the readability of printed documents.The sed utility is a stream editor that allows you to search for and replace text strings in a file. You can execute sed commands at the command line or you can run a command file to replace characters and strings in a specified data file. ed was the first text editor for UNIX text files.txt file: sed -e '/^line. or to extract information for other programs. Because the early line editors lacked textformatting capability. However. PERL was developed originally as a data reduction language capable of processing large quantities of data efficiently. In the following example. Summary Developed to support a documentation project in the AT&T/Bell Telephone Company. and filemanipulation tool that bridges the gap between shell and C programming.print} profile PERL PERL (Practical Extraction and Report Language) is a portable text. the sed command deletes the first two lines of the easynomad. and Kernighan. such as PERL commands.*one/s/line/LINE/' -e '/line/d' easynomad. Aho. . sed.txt awk Named after its originators. awk is a complete patternscanning and processing language. awk {$2="". Its syntax resembles the syntax you use in shell programs and in C programming. process. which is especially useful in the case of lengthy system logs and e-mails. and grep as built-in functions. This allows you to delete lines of text by "replacing" them with nothing. it is most commonly used as a UNIX command-line filter to reformat the output of other commands. You can run awk commands from the command line as a simple text-processing tool. It allows you to extract parts of a large body of text. In the following example.

and PERL is a text. All rights reserved. 1. It processes one line of standard input at a time and returns the results as standard output. Introducing sed Unlike text editors that allow you to alter a file by moving the cursor on the screen. sed allows you to perform search and replace operations. and PERL. . The three most commonly used text-processing tools are awk.More comprehensive text-processing tools such as TeX ± which is used in scientific environments ± and Emacs ± which is used for programming ± were developed to improve on the runoff tool. sed is a noninteractive line editor. process. Awk allows you to perform pattern-scanning and processing. Table of Contents | Top of page | | Abstract | | Plain text | | Early text processing | | Text formatting | | TeX and LaTeX | | Emacs | | Shell programming tools | | Summary | Copyright © 2003 SkillSoft PLC. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft PLC in the United States and certain other countries. and file-manipulation tool. sed. | Print | Contents | Close | UNIX editing with sed Learning objective After completing this topic. All other logos or trademarks are the property of their respective owners. you should be able to explain how to use the sed line editor.

you can also use it to append. sed works as a filter that searches for a specified pattern and takes a specified action if it matches the pattern. However. You can also use sed to delete leading or trailing spaces and consecutive blank lines. it processes input via a keyboard and returns output to the screen. 2. You can perform many of these functions using the vi text editor. As a result. 4. Sed applies each editing command to the first line in a file and then moves on to subsequent lines one at a time. You can execute sed operations by y y using the -f flag creating a sed executable file using the -f flag . In its simplest operation. an entire file is never loaded into memory. It doesn't alter original files. What do you think you can use sed for? Options: 1. delete. sed provides a better solution than the vi text editor for working with multiple text files. 5. display. Converting double and triple spacing in a file Converting DOS newlines to UNIX newlines Deleting leading or trailing spaces and consecutive blank lines Performing substitutions on all or specific lines Sorting information in a text file Answer You can use sed to convert line spacing in a file and to convert DOS newlines to UNIX newlines. However. 3. or insert text. and to perform substitutions on all or specific lines. You often use sed to perform search and replace operations on the content of specified text files. Question Because sed works with open format files ± or plain text files ± it is portable and supports a wide range of text applications.In most cases.

Option 4 is incorrect.txt edit.sed reports. Question You have stored sed editing commands in a text file named edit. creating a sed executable file An executable sed script contains the line #!/usr/bin/sed -f.sed on a file called memo.You can create a script containing only editing commands. Option 3 is incorrect. which you can then pass as a file for execution by sed using the -f option.sed Option 2 is correct. 3. The file containing the sed commands is provided after the ±f option. This command would work if edits.txt | sed ±f edit.sed were an executable file.txt./ command.txt to edit the reports. the code sed -f sample. For example.txt sed ±f reports. cat edit. Which sed command do you execute at the command line to edit the file reports.sed. 2. However./edit.sed reports.sed . It is possible to pipe input into sed. but to do so. .sed | sed reports.txt sed ±f edit. and then you provide one or more files for sed to operate on. which allows you to run it through the shell using the . and not after the file on which sed is to operate on.txt file using the sed commands in edit.sed reports. You use the ±f option to specify the file containing the sed commands. you need to use the chmod command to give the file execute permissions before you can run it. Option 1 is incorrect. but in this example it just contains sed commands.txt Answer You use sed ±f edit. you would use the following command: cat reports.sed memo.txt? Options: 1. 4.txt causes sed to execute the commands in a file called sample.sed.

for example. The most commonly used regular expressions with the sed command are y y y y y ^ The ^ expression attempts to match a pattern string with the beginning of a line in a specified file. gawk. $ The $ expression attempts to match a pattern string with the end of a line in a specified file. you follow the command with a string that includes the following components: y y y editing command regular expression and pattern string replacement text For instance.2. For instance. Note The sed utility supports most of the regular expressions that other UNIX text utilities ( such as awk. the command sed 's/[ ]*//' easynomad will delete any spaces in the file. the code sed 's/^night/day/' substitutes the word "night" with the word "day" when the word night occurs at the beginning of a line. For instance. If a ^ replaces a line number. and grep ( and UNIX shells support. Matching expressions with sed To specify a sed command in a script or on the command line. the command sed 's/ $//' easynomad will replace any space character ( indicated by a forward slash ( that occurs at the end of a line. * The * expression attempts to match any occurrences of a specified character with characters in the content of a specified file. ^ $ * ? [ ] . For instance. it denotes the first line in a file. the command sed 's/^Thu /Thursday/' easynomad will substitute Thu with Thursday only when Thu occurs at the beginning of a line.

The -s option to sed substitutes anything matched by the first expression with the contents of the second expression. Deletes the last word on each line Answer The command sed 's/ *$//' test1 deletes all trailing spaces from each line. the command sed 's/[Ee]asy[Nn]omad/EasyNomad/g' easynomad will substitute uppercase and lowercase instances of the letters "e" and "n" with the word "EasyNomad. sed 's/[ ][^ ]*$//' test2 deletes the last word on each line. The $ matches the end of a .? The ? expression attempts to match one instance of a specified character with the content of a specified file. See if you can match each sed command with the function it performs. the metacharacter * matches the preceding character ± a space ± zero or more times. Deletes all trailing spaces from each line B. the command sed 's/?D/4/' easynomad will substitute the first instance of the letter D with the number 4. For instance. sed 's/ *$//' test1 2. sed 's/^$//' test3 Targets: A. Finds all blank lines by identifying each line end that follows immediately after a line beginning C. In this case. For instance. [ ] The [ ] expression attempts to match the content of the square brackets with a specified pattern string. and sed 's/^$/ blank line/' test3 finds all blank lines by identifying each line end that follows immediately after a line beginning. Options: 1." Question Sed allows you to use combinations of regular expressions. sed 's/[ ][^ ]*$//' test2 3.

For instance. For instance. control passes to the end of the script.you would adapt the expression as follows: sed 's/^$/---/' test3 In addition to the substitute command (s). you can use the insert (i). These commands transfer control to a line containing a specified label. but which contains anything other than a space thereafter.][^ ]*$ matches any string that starts with a space. ^$ matches the start and end of an empty line." In the example sed 9 a\Copyright EasyNomad 2003. the sed command appends the string "Copyright EasyNomad 2003" after line 9 in a specified file. The effect of this is to match every word at the end of a line. If the label does not appear in the script. You can preface sed commands with line numbers to specify which lines in the input file are to be modified by the sed command. You can use two advanced sed commands ± branching (-b) and testing (-t) ± to rearrange the order in which portions of a script execute. the circumflex (^) matches the start of a line or string.line.txt. To insert a paragraph separator such as --. the effect is to delete all trailing spaces from each line. but testing requires an s (substitution) command to change the current line before control is passed. The -s option to sed substitutes anything matched by the first expression with the contents of the second expression. the command sed '$d' text. 2 s/tourist/tourists/ looks for the string "tourist" in line 2 of a specified file and replaces it with the string "tourists. append (a). and is at the end of a line. Because nothing is specified in the second expression. If you wanted the string inserted before line 9. The expression [. and delete (d) commands with the sed command.txt deletes the last line in a file named text. Branching passes control to the end of the script automatically. with examples of their usage. you would specify the command sed 9 i\Copyright EasyNomad 2003. Note The UNIX man pages provide a full listing of the sed options. . When it is not preceding a class or range. In this example.

For example. Option 1 is correct. Option 2 is correct. 2. 2. 3. You use the i command to insert text in sed. You use the ±n option to suppress printing of all output except that explicitly matched by the sed command. 4. You can specify the line on which a sed command will operate You use the a command to append text in sed You use the i command to insert text in sed You use the ±n option to insert new lines Answer The a command appends text to the specified location. 4. Matches a class of characters . 3. this command adds the text "circa 1848" to the start of line 10: sed 2 i\circa 1848 Option 4 is incorrect. For example. Options: 1. this command adds the text "circa 1848" to the end of line 10: sed 2 a\circa 1848 Option 3 is correct. Options: 1.Question Identify the true statements regarding sed commands. Question Match the sed regular expression characters with their descriptions. You use the a command to append text in sed. You can precede your sed command with the number of the line on which it is to operate. ^ $ * [ ] Targets: A. while the i command inserts it. You preface sed commands with the specific line on which you want them to operate.

The ^ command matches the beginning of a line.txt Name Home_Number Cell_Number E-Mail Greg (100) 100-555-1111 100-555-1112 GregL@easynomad. bash -2.B.05a$ sed 's/100-/(100) /' phonelist.com Tanya (100) 555-2222 100-555-1113 TanyaS@easynomad.com Sam 101-555-1111 101-555-2222 SamO@easynomad. In this example. You use [ ] to match a class of characters and * to match the preceding character. Matches the beginning of a line D. zero or more times.com . The output shows that only the first instances of "100-" in each line were changed. the sed command will delete any new line that starts with a space: sed '/^ /d' You match the end of a line with the $ command. zero or more times. Matches the end of a line Answer You match the start of a line with ^ and the end of a line with $. To do this. this command changes DOS newlines to the UNIX format: sed 's/. Editing text with sed Let's say that you have a simple phone list that you need to extract data from using sed commands. Matches any number of the preceding character C. the following sed command will delete any line that starts with a number: sed '/^[1-9]/d' 3. you enter the code shown here.com Daniel (100)555-3333 101-555-1114 DanielB@easynomad. For example.$//' The * command matches the preceding character. For example. The following sed command will replace the character 2 with 1: sed 's/2*/1/g' The [ ] command matches a class of characters.with (100) so that you can distinguish the area codes from the rest of phone numbers more easily. Suppose that you begin by replacing instances of 100.

txt Name Home_Number Cell_Number E-Mail Greg (100) 100-555-1111 (100) 555-1112 GregL@easynomad. . changes only the data output and not the original text.com bash -2. its original content doesn't change.com Tanya 100-555-2222 100-555-1113 TanyaS@easynomad.com Sam 101-555-1111 101-555-5555 SamO@easynomad. bash -2. Using the p option prints Tanya and Sam's records because these are the only records that contained the string "2222".05a$ You can use the q (quit) option to display lines up to and including a specified line ± line 5.$d/' phonelist.05a$ sed 's/4.txt Name Home_Number Cell_Number E-Mail Tanya 100-555-5555 100-555-1113 TanyaS@easynomad. for instance.05a$ The example here shows how you can use the d (delete) option to display a specific number of lines ± in this case. bash -2.com bash -2.05a$ Note Even though you've used s (substitution) options on the phone list file.com bash -2. you use the g option. the first three lines ( in a file.txt Name Home_Number Cell_Number E-Mail Greg 100-100-555-1111 100-555-1112 GregL@easynomad. The command to change "100-" to "(100)" . both Greg and Tanya's cell numbers are now prefixed with "(100)".com Daniel (100) 555-3333 101-555-1114 DanielB@easynomad. For instance.05a$ To change all instances of "100-" in each row.Nick (100)555-4444 101-555-1115 NicholasN@easynomad.com bash -2.com Tanya (100) 555-2222 (100) 555-1113 TanyaS@easynomad. bash -2.05a$ sed 's/100-/(100) /g' phonelist. Let's say that you want to replace the string "2222" with "5555" and to instruct sed to print only the lines affected by the change.05a$ sed 's/2222/5555/p' phonelist.com Nick (100) 555-4444 101-555-1115 NicholasN@easynomad. in this example.com Sam 101-555-1111 101-555-2222 SamO@easynomad.

com bash -2.05a$ sed 's/555/55/g' > newphone.555-3333 101-555-1114 DanielB@easynomad. bash -2.txt Name Home_Number Cell_Number E-Mail Greg 100-100-555-1111 100.txt Name Home_Number Cell_Number E-Mail Greg 100-100-55-1111 100-55-1112 GregL@easynomad. it's advisable to write a script that you can then run against the file. bash -2.com Nick 100-555-4444 101-555-1115 NicholasN@easynomad.05a$ If you want to execute a number of sed commands on the same text file. In this example.05a$ You can direct the output of a sed command to a new file.com Nick 100-55-4444 101-55-1115 NicholasN@easynomad.com bash -2.com Tanya 100-555-2222 100-555-1113 TanyaS@easynomad.bash -2. you use the d (delete) option with the specification that all lines beginning with the word "Sam" be excluded from the output.com Daniel 100-555-3333 101-555-1114 DanielB@easynomad. the script contains a number of s (substitution) commands.555-1112 GregL@easynomad. the code replaces a 3-digit string with a 2-digit string and saves the output in a new text file named newphone.com Nick 100-555-4444 101-555-1115 NicholasN@easynomad. In this example.txt Name Home_Number Cell_Number E-Mail Greg 100-100-555-1111 100-555-1112 GregL@easynomad.com Daniel 100-55-3333 101-55-1114 DanielB@easynomad.com Sam 101-55-1111 101-55-2222 SamO@easynomad.com Tanya 100-55-2222 100-55-1113 TanyaS@easynomad.com bash -2.com Tanya 100-555-2222 100-555-1113 TanyaS@easynomad. cat sedscript s/555/55/g s/100-/(100) /g s/101-/(101) /g s/easynomad/EasyNomad/g .05a$ sed 's/^Sam/d' phonelist. To do this.05a$ Let's say that you want to print all records in the phone list except Sam's record.com Daniel 100.txt.05a$ sed '5q' phonelist.

When you run a sed script against the phone list text file, it outputs the table with all the substitutions in the script implemented. bash -2.05a$ sed -f sedscript phonelist.txt Name Home_Number Cell_Number E-Mail Greg (100) 55-1111 (100) 55-1112 GregL@EasyNomad.com Tanya (100) 55-2222 (100) 55-1113 TanyaS@ EasyNomad.com Sam 101-55-1111 (101) 55-2222 SamO@ EasyNomad.com Daniel (100) 55-3333 (101) 55-1114 DanielB@ EasyNomad.com Nick (100) 55-4444 (101) 55-1115 NicholasN@ EasyNomad.com bash -2.05a$

Summary
Sed is a noninteractive line editor, which processes one line of standard input at a time and returns the results as standard output. To specify a sed command in a script or on the command line, you follow the command with regular expressions, the pattern string that you want the command to locate, and replacement text for this string. Sed allows you to perform a range of text edits on plain text files, either as single or multiple command-line instructions or by passing multiple instructions in a script.

Table of Contents
| Top of page | | Learning objective | | 1. Introducing sed | | 2. Matching expressions with sed | | 3. Editing text with sed | | Summary |
Copyright © 2003 SkillSoft. All rights reserved. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

Creating a configuration script

Learning objective

After completing this topic, you should be able to use sed in a UNIX shell script to edit a file.

Exercise overview
In this exercise, you're required to create a new configuration file and perform a sed substitution. This involves the following tasks: y y redirecting sed output substituting a text string

Task 1: Redirecting sed output
Let's say that you want to adapt the configuration file named "hosts" on the primary GLEESON server for use on the secondary server, without changing the original file. You decide to use sed to search and replace host addresses and to save the output as a new file called "en_hosts".

Step 1 of 2
Let's say that you want to change all instances of "190" to "192". See if you can type the sed command that will substitute the 190 string.

sed MISSING CODE

Result
You enter 's/190/192/g' to specify the global substitution that will change all instances of "190" to "192."

Step 2 of 2
Let's say that you want to create a new configuration file containing the changed output. Choose the code that you think will specify hosts as the input file and en_hosts as the output file.

$ sed 's/190/192/g' MISSING CODE Options: 1. en_hosts > hosts 2. hosts > en_hosts 3. en_hosts < hosts

Result
The code that specifies hosts as the input file and en_hosts as the output file is hosts > en_hosts Option 1 is incorrect. This option uses en_hosts as the input file and hosts as the output file. Option 2 is correct. The data on the left of the > redirector is written to the file on the right of the redirector. Option 3 is incorrect. This command would redirect the hosts file as an argument to the command on the left of the redirector. Since en_hosts is a file, this command will generate an error.

Task 2: Substituting a text string
Step 1 of 2
Let's say that you need to change all instances of "gleeson" to "gleeson_assoc" in the en_hosts configuration file. Choose the code that you think will substitute all the text strings that match "gleeson."

$ sed MISSING CODE Options: 1. 2. 3. 4. 's/^gleeson/gleeson_assoc/g' 's/gleeson_assoc/gleeson/g' 's/gleeson/gleeson_assoc/p' 's/gleeson/gleeson_assoc/g'

Result

You enter 's/gleeson/gleeson_assoc/g' to specify the substitution that will change all instances of "gleeson" to "gleeson_assoc" in the en_hosts configuration file. Option 1 is incorrect. This would only replace the string "gleeson" if it appeared at the start of a line. Option 2 is incorrect. This would replace gleeson_assoc with gleeson, instead of vice versa. Option 3 is incorrect. The g flag is required to ensure the each instance is replaced, not just the first. The p flag sends the results of each replacement to standard output. Option 4 is correct. You use the s command with the g flag to perform global substitutions. The first term is the search term that is replaced with the second term.

Step 2 of 2
See if you can complete the sed command to output the new configuration information to screen.

$ sed 's/gleeson/gleeson_assoc/g' MISSING CODE

Result
You enter en_hosts to specify the filename of the new configuration file.

Table of Contents
| Top of page | | Learning objective | | Exercise overview | | Task 1: Redirecting sed output | | Task 2: Substituting a text string |
Copyright © 2003 SkillSoft. All rights reserved. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

Programming with awk for UNIX

Awk allows you to perform a variety of data processing tasks. 2. awk scans and processes patterns in a text file. Viewing a text file as a table of records and fields Using variables to manipulate the text as if it were data in a database Generating formatted reports Performing search and replace operations Answer Awk allows you to view text files as tables of records and fields. you should be able to explain how to use awk. 3. loops. analysis. and arithmetic and string operators. 4. and generate formatted reports. However. you need to specify y y the input data the awk program or script the input data . and reporting. use variables to manipulate the text as if it were data in a database. To use the awk command. Aho. Which of the following operations do you think awk allows you to perform on a text file? Options: 1. and Kernighan. including data extraction. Weinberger. its extensive programming syntax classifies it as a programming language rather than as a simple text utility. Introducing awk Like the sed line editor. Note Awk derives its name from the surnames of its developers. such as conditionals. 1. Question Awk uses common programming constructs.Learning objective After completing this topic.

The input data is the data that awk is to process. You can also provide standard input by piping another program or UNIX command into awk. In addition to the input data and the awk script. This is an alternative to entering the required source code on the command line. This sets the specified variable prior to execution. the awk program or script The awk script specifies how the input data is to be processed. to set the field separator that the input data uses to a colon. you can specify options with the awk command using the following syntax: y y y y -f program file program source -F character -v var=value -f program file You can use the -f option with the name of a program file to specify the file containing the awk program code to execute. You can specify this data as one or more files or you can use standard input from the keyboard after executing the awk command. -v var=value You use the -v var=value option to initialize a variable on the command line. you need to enclose the code in single quotes to prevent it from being interpreted as shell code. This is an alternative to using the -f option to specify the name of a program file. Question . you enter -F:. For instance. You can specify the awk script as a file passed with the awk command or you can specify it on the command line. program source You can enter the program source ± the code that the awk program needs to execute against ± on the command line. When you enter the program source on the command line. -F character You use the -F character option to set the field separator in the input data to a character other than the default white space.

awk [-v var=value] [-F field separator] [--] 'pattern {action}' var=value datafile(s) You enclose the actions that awk must perform in braces ({}) so that awk can differentiate them from their associated patterns. you can store the program instructions in a text file to read in from the awk command line. . Option 4 is correct. Awk only operates on a single data file per command You can enter the program code for awk on the command line You can initialize variables from the awk command line You use the ±f option to specify a file containing awk program code Answer Awk program code can be entered on the command line or you can use the ±f option to read it from a file. Awk building blocks Awk works by matching a specified pattern with data in an input file and taking a specified action on all lines that contain pattern matches. Option 1 is incorrect. 4. 2. You can initialize variables used by awk from the command line. 3. For instance. you use the following basic syntax. If you have a complex awk program that you want to reuse.Identify the statements that correctly describe the use of awk. the code fragment deposit = $5 instructs awk to use the value in column 5 for calculations involving the deposit. A string of characters placed between forward slashes (//) is called a regular expression. you can use a matching operator such as the equals (=) sign. When awk encounters any occurrence of that pattern within a line. You can specify multiple files for an awk program to use as input. 2. To select records on the basis of data in a particular field. You can specify the patterns to be matched and the actions to be taken as a single awk command line statement. Option 3 is correct. it will select the line. Options: 1. Option 2 is correct. To specify an awk command. You can use the ±v option on the awk command line to name a variable used in your awk code and assign it an initial value.

this code prints the string "EasyNomad" to screen. Rather. The BEGIN statement is called once only before awk reads any data lines.In addition to regular expressions in an awk command. you can specify awk variables only when they're needed.05a for i in terry larry mary do mail $i << END $(date) Have a good holiday $i! END quit exit clear { en='EasyNomad' print en. less than (<). The END statement is called after awk has read and processed all lines. And you can address both regular and relational expressions in compound forms using the logical OR (||) and logical AND (&&) operators. The END statement allows you to specify actions ± such as printing an ending text line or calculating cumulative variables such as line counts or column totals ± that need to occur after awk has processed the last input line. and less than or equal to (<=). For instance. The BEGIN statement allows you to specify actions ± such as resetting variables or creating column headings for output ± that need to occur before awk starts processing input lines. you can search for patterns using relational expressions such as greater than (>). bash-2. } .05a$ bash: / : is a directory bash-2. You don't need to specify awk variables before you use them. END is called after awk has finished processing the last file. If the source program for awk includes multiple files.

and match. y These are divided into arithmetic functions ± such as cos. These arrays are known as associative arrays because you can reference the values they include using a string or an index number. int. whereas the $0 expression represents the number of the current record as a single variable. length. both separators are newline characters. RS and ORS The RS and ORS variables represent the input record separator and the output record separator respectively. which you can use in awk scripts to return values needed by the script. . you can write a function that returns values sorted in a specified order. Awk updates other reserved program variables ± such as current record number ± automatically. A value with its index number is known as an element. By default. Awk allows you store sets of values in associative arrays. which means that awk interprets each line in an input file as a separate record. The most commonly used reserved program variables are y y y y NR or $0 NF or the $1-$n syntax FS and OFS RS and ORS NR or $0 The NR variable denotes the number of the current record. sin. Awk provides a number of functions. and rand ± and string functions ± such as index. FS and OFS The FS and OFS variables represent the input field separator and the output field separator respectively. NF or the $1-$n syntax Both the NF variable and the $1-$n syntax denote the number of fields in the current record. For instance.Awk provides reserved program variables. You can change some of these variables ± such as the default field separator. log. It also appends a newline character to the end of each record that it sends to standard output. exp. Awk allows you to define your own functions for use in multiple scripts by using the function command to specify a list of statements.

the END statement is called after each is processed . If multiple files are called. Question Which statements accurately describe awk syntax? Options: 1. but you can use the ±F option to define the field delimiter. The $0 field descriptor matches every field in a line of input. The first argument to the awk command The first field in a line of input An entire line of input A null variable Answer The $0 expression is an awk field variable that matches an entire line of input.You use this syntax to create an array. all variables have a null value until a value is assigned to them. array[index] = value You can use a special for structure with an awk array to loop through the array elements. Option 2 is incorrect. 4. In the syntax of the shell command interpreter. the $0 positional parameter references a command itself. 3. However. The first field in a line of input is referred to with the $1 field descriptor. for(elem)action Question In terms of awk syntax. 2. Option 3 is correct. what does the $0 expression denote? Options: 1. In awk. Option 1 is incorrect. it acquires a different meaning in the syntax of the awk command interpreter. The default field delimiter is a space. using this syntax. Option 4 is incorrect.

Before entering complex formatting instructions. after all the input has been processed. before processing any input. you can use actions defined in the END statement to manipulate the processed data. You can use the BEGIN statement to perform initial operations. The code awk '/#/ {print "Comment found "}' /etc/hosts will print "Comment found" for each line that contains at least one hash sign anywhere in the line. you may want to know whether a configuration file contains comments ± indicated by a hash sign (#) ± and. . while the END statement specifies actions taken after processing all input.2. you want to check whether there are any lines in the file that exceed 80 characters. You use the END statement to specify actions that are performed after input is processed Answer The BEGIN statement specifies actions to be taken before processing all input. Option 3 is correct. For instance. where they are located in the file. You don't want the lines to wrap. To do this. such as creating columns or assigning values to variable. Option 2 is incorrect. you use the code awk 'length > 80' hosts. Once all input has been processed. Option 4 is correct. You must declare any variables used in your awk program on the command line 3. the END statement is called only once. Let's say that you want to print a text file to a screen that is limited to a width of 80 characters per line. As is generally true of shell scripting. Programming with awk One of the main uses of awk is to find out about the content of a text file. awk variables can be initialized as you need them. if so. You can use awk to reformat text files awk for improved readability or for export into other applications. 3. Option 1 is incorrect. You use the BEGIN statement to specify actions that take place before processing any input 4. Irrespective of the number of files on which the awk code operates.

txt to double-line spacing in a file named nomad1. The code awk -F":" '{ print $1 }' /etc/passwd. When awk processes the print $1 command. In this example.txt changes the single line spacing in the file nomad. accompanied by the text strings enclosed in double quotes. the awk program initialises the x variable with a value of 0. and increments it by one. it will print out the first field that appears on each line in the input file. Option 1 is correct. Awk can process text that has been broken into multiple logical fields. The number of non-blank lines in a file 3. Question Awk allows you to perform integer and floating point mathematical operations on input files. . The print command sends the value of x to standard output. And you can reference individual fields in an awk script. prints a list of all user accounts on the local system. A printout of all blank lines in a file } Answer The code will calculate the number of blank lines in a file and return the result to the screen. the code awk '{print . for example. :)" Options: 1.txt. What do you think the output of the following script will be? BEGIN { x=0 } /^$/ { x=x+1 } END { print "I found " x " blank lines. You use single quotes in this way to hide special characters from the shell.txt > nomad1. the single quotes allow the use of double quotes in the awk expression.For instance. In the code. print ""}' nomad. The number of blank lines in a file 2. the -F option changes the field separators between multiple fields in the passwd file from the default spaces to colons. Each time a blank line is detected.

such as cat and grep. you can use it to determine whether a file includes comments or to reformat a file for improved readability.^$ matches every blank line. including data extraction. The print command only prints the value of the x variable and some helpful text. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All other logos or trademarks are the property of their respective owners. The regular expression that increments the x variable . The pattern that is matched ± in this case blank lines ± is not automatically printed. Awk building blocks | | 3. the content of the text1 file is piped to awk for pattern matching. $1/$2}' > text2. Table of Contents | Top of page | | Learning objective | | 1. For instance. In the example cat text1 | awk '$1 < $2 {print $0. You can use awk with other UNIX commands. Introducing awk | | 2.Option 2 is incorrect. | Print | Contents | Close | . and reporting. The output of the command will be stored in a new file named text2. All rights reserved. analysis. not lines containing characters. Option 3 is incorrect. Programming with awk | | Summary | Copyright © 2003 SkillSoft. Summary Awk allows you to perform a variety of data processing tasks. One of the main uses of awk is to find out about or change the content of a text file. Awk works by matching a specified pattern with data in an input file and taking a specified action when it locates this pattern.

Programming with the shell The shell is an interface between the user and a UNIX operating system. Once you've prototyped an application. You can combine these functions with UNIX command-line programs. You can use shell scripting to automate tasks that need to be performed in sequence. Shell programming is useful for y y y automating tasks prototyping system administration automating tasks A shell program ± or script ± allows you to specify operations in a certain sequence. The shell supports a set of functions implemented as keywords that provide a simple programming language. system administration Shell scripts run at system bootup to restore system configurations and to set up services.UNIX shell programming principles Learning objective After completing this topic. as well as the transition from one run-level to another. They manage the initialization and shutting down of essential system services during system startups and shutdowns. 1. You can create shell scripts ± consisting of ASCII text files ± that the shell interprets and the operating system executes. you should be able to explain the principles of logical flow in a shell program. . you can rewrite it in languages such as C++ and Java to improve its performance and extend its functionality. prototyping You can use shell programming to prototype complex applications so as to provide proof-ofconcept implementations and to test logical functions. such as transferring files using the File Transfer Protocol (FTP) and then e-mailing users once the files have been downloaded.

. Developing a proof-of-concept application B. Scripting tasks that are performed repeatedly Answer Automation involves scripting repetitive tasks. C++. rather than shell scripting. and optimization of shell scripts used to initialize a system is an important part of system administration. Optimization of system initilization scripts C. designing proprietary applications.System administrators can write shell scripts to analyze the behavior of a system and to modify it. developing proof of concept applications is an example of prototyping. Prototyping 3. 2. 3. For which of the following purposes do you think a compiled language is more appropriate than shell scripting? Options: 1. Creating applications with cross-platform portability Designing proprietary applications Improving system performance Manipulating graphics or GUIs Prototyping an application Answer You should use more powerful scripting languages than shell scripting for improving system performance. as well as to automate repetitive tasks. System Administration Targets: A. Question Match the action to the example. Automation 2. 4. Question In certain cases. and manipulating graphics or GUIs. Options: 1. or Java. you should use compiled languages such as C. 5.

indenting an if then fi statement or a do while loop makes it easier to verify that you've completed the required code correctly so that subsequent code will execute.Repetitive tasks can be automated by shell scripts. together with the programming language components required to achieve the specified tasks. Pseudocode consists of an informal written plan that describes what each item of code must do. Services and system configurations on UNIX systems are usually initialized by shell scripts. Ensuring that each section of code works correctly before you continue programming simplifies the debugging process because it allows you to isolate incorrect code more easily. Core tools available in most programming languages ± including shell scripting ± include . Because shell programs are relatively simple to write. debugging during code construction You should debug a program as you work on it ± rather than after completing it ± to verify that each logical section of code works correctly. 2. General programming principles that make it easier to write and interpret programs include y y y writing pseudocode debugging during code construction indenting code for readability writing pseudocode To identify the steps that a program needs to include. For instance. it's often useful to test procedures in the shell before incorporating them into programs written in more sophisticated languages. indenting code for readability You should enter spaces between commands and indent code to make it more readable. Programming fundamentals Programming effectively requires that you first determine the solution that a program must provide. if every project you work on has a similar directory structure. You then plan the components that the program requires to do this and determine how the components will fit together to execute the required tasks. you can automate the process of generating the directories for a particular project. For example. so understanding shell programming techniques is essential to optimizing your system. you should use pseudocode.

Information is passed to functions in the form of arguments. the then statement executes. A function can perform operations based on the arguments passed to it. the else statement executes to repeat the request that the user enter a valid number. functions Functions ± also known as procedures or subroutines ± consist of code that implements a program that you can embed and reuse in a shell script.y y y y conditional statements functions loops variables conditional statements You use conditional statements to control the flow of statement execution in a program. You use if then else statements to check a condition and then to perform an action based on whether the condition evaluates to true or false. If the if statement evaluates to false. If the condition specified in the if statement in this example evaluates to true. They allow programmers to create modular code that is easier to maintain and extend than code implemented as a single routine. and return values for use in the code from which the function is called. The following code is shown on screen: echo "Please enter a value less than 10:" read VALUE check_value () while [ $VALUE ±gt 10 ] do echo "Please enter a value less than 10:" read VALUE done echo "The value you have chosen is $VALUE" } check_value VALUE loops . In the example shown here. the check_value function ensures that a variable set from standard input corresponds to an appropriate range of values.

You can also use a loop to test a condition and repeat the process until the condition returns an exit status of 1 to indicate that it is no longer true. Question Identify the statements that describe sound programming practice. When naming a variable. You can use the local keyword in a function to define a variable that is available only to that function. The following code is shown on screen: echo "Enter a number" read NUM COUNT=1 while [ $COUNT -le $NUM ] do print "Hello World" COUNT=$((COUNT+1)) done variables Variables associate a name with a location in memory that contains data. Options: 1.You use loops to count through a list and to apply a certain action to each element in that list. the code will print "Hello World" while the count is smaller than or equal to 5. 2. the loop will print "Hello World" the number of times that the user specifies. 3. Debug programs once you've completed the code Indent code and use whitespace to improve readability Use functions to create modular code Use pseudocode to plan programs Answer . You should choose a descriptive name. This is useful for maintaining modularity in complex programs. 4. You can use the name to access and change the data. for example. In this statement. Modern shells ± such as the Korn and Bash shells ± provide for the use of variables with both a local and global scope in shell scripts. If the user enters a value of 5. And a useful convention for shell scripts is to capitalize variable names. you should ensure that the name isn't used by a function.

The core tools for programming include variables. Question Why would you write pseudocode? Options: 1. and . Option 2 is correct. it makes debugging and maintenance considerably easier. Option 4 is correct. Pseudocode is not interpreted. Option 2 is correct. and to use functions to create modular code. to use whitespace to improve the legibility of your code. so it can't be debugged. To assist with debugging procedures 2. Psuedocode is particularly useful for organizing your approach to complex programming tasks. and simplifying system administration. Shell programming is useful for automating tasks. loops. Option 1 is incorrect. Option 3 is correct. creating prototype programs. Although use of whitespace and indenting is not a functional requirement. To identify the logical steps in a program 3. and thereby improving efficiency. it is difficult to accomplish complicated programming tasks without first breaking them down into steps. Although pseudocode isn't needed for simple tasks. To make your code more readable Answer Pseudocode helps you identify the logical steps needed in your program. so it doesn't affect the readability of your code. Pseudocode isn't included in your actual program.It is good practice to plan your programs in psuedocode. Option 1 is incorrect. Option 3 is incorrect. Creating modular code through the use of functions makes your code easier to maintain and reuse. you should debug code as you write it. You can use shell scripts to instruct the shell to perform operations in a specific sequence. To reduce errors and save time and effort. conditional statements. Summary The shell allows users to interact directly with a UNIX operating system.

Programming fundamentals | | Summary | Copyright © 2003 SkillSoft. Testing conditions Programmers frequently need to make the execution of their code dependent on certain circumstances being met. Table of Contents | Top of page | | Learning objective | | 1. debugging a program as you construct it. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All rights reserved. Programming with the shell | | 2. Question You perform tests by evaluating conditional expressions. The shell provides a number of tools for testing conditions that simplify the process of building conditional execution into shell scripts.functions. What do you think are uses of conditional expressions? . if your code needs to append data to a file. it is a good idea to check that the file exists before executing code that tries to append data to the file. and indenting code for readability. For instance. 1. you should be able to use conditional expressions to provide flow control in shell programs. All other logos or trademarks are the property of their respective owners. | Print | Contents | Close | Testing conditions in the UNIX shell Learning objective After completing this topic. General programming principles that you should follow include writing pseudocode.

You can test conditional expressions using three different forms of syntax: y y y [ expression ] test expression [[ expression ]] In the syntax. For example. the command will return an exit status of 0 if the conditional expression is true and an exit status of 1 if it is false. you can test whether x is less than or equal to y using the following statements: [[ $x le $y]] [ $x le $y ] test $x le $y Compound expressions combine two or more expressions using the y y double ampersand operator (&&). and test file attributes. evaluate and compare strings. where | | means "or" . where && means "and" double pipe operator (||). you're less likely to need to resort to quoting. You must include a space between the expression and the brackets. 4. The [[ « ]] command is preferable to the test and [ « ] commands because it helps avoid syntax errors. Determining specific outcomes Evaluating and comparing integers Evaluating and comparing strings Testing file attributes Answer You can use conditional expressions to evaluate and compare integers.Options: 1. 2. it will return a syntax error. When testing an expression. For instance. 3. because wildcard expansion and word splitting aren't automatically applied to expressions in the [[ « ]] command. expression is the condition that you are testing. when you compare two variables using the test and [ « ] commands and one of the variables is set to null or is unset. Furthermore.

a student's class mark has to be higher than the average mark of the class and higher than 80. [[ expression1 && expression2 ]] Suppose that you want to ensure that two conditions are met before printing a message. In this case.For example. Spaces on either side of the [ symbol are not interpreted by the shell 2. $[[ $class_mark > $class_average && $class_mark > 80 ]] \ && print "Your class mark is very high" You can use the [[ « ]] syntax together with string operators to test variables. The [[ condition ]] syntax is backwardly compatible with the Bourne shell Answer . Options: 1. The ±n option to the test command returns a value of 1 if the variable being tested has a null value 3. you can combine two expressions using the syntax shown here. set_var (){ echo "Enter a variable" read VAR } while [[ -z $VAR ]] do set_var done Question Identify the statements regarding the test command that are true. You can use conditional operators within a test command 4. The following string operators are useful for checking that variables used in a program have been assigned appropriate values: y y y -n ± true if length of string is not zero -o ± true if option is set -z ± true if length of string is zero The following code fragment executes the set_var function until the $VAR variable is assigned a value that is not null.

Option 3 is correct. the format options to the date command assign values such as "Saturday" and = != < > . For example. The shell returns a value of 1 when a condition evaluates as false. Option 2 is correct. Conditional expressions can form part of conditions evaluated by the test command. this code tests whether the string "Belize" has been assigned to the $DESTINATION variable and if it has. You can use the && operator to require two conditions to be met. The ±n option is used to test that a a variable has been assigned a non-null value. 2. Option 4 is incorrect. then that variable has a null value. and you use the || operator to require only one of two conditions to be met. Option 1 is incorrect. The [[ condition ]] syntax is supported by the Korn shell. prints the message "flights available. The [ and ] symbols are commands. Consider the following code: DOTW=$(date +%A) [[ $DOTW = S* ]] && echo "Weekend!" In this case.If test ±n returns a 1 when testing a variable. so if you neglect to include white spaces on either side the shell will return a syntax error." [[ $DESTINATION = "Belize" ]] && print "flights available" You can use the following string operators to compare strings: y y y y = You use the [[ string = pattern ]] syntax shown here to test if a string matches a pattern constructed using a combination of literals. but not by the Bourne shell. Conditional statements You can compare one string with another string using the syntax [[ string1 = string2 ]].

and if it does. the string "Workday!" is echoed. the string "Weekend!" is echoed. Consider the following code: BIGGER=$(bcd) [[ $BIGGER > abc ]] && echo "Bigger" In this example. != You use the [[string! = pattern ]] syntax to test if a string doesn't match a pattern. The syntax returns a true value if the string fails to match the specified pattern. the DOTW variable is tested to see whether it does not start with an "S". the string "abc" is smaller than "bcd" and so the code echoes the string "Smaller."Wednesday" to the DOTW variable. the string "bcd" is greater than the string "abc". The DOTW variable is then tested to see whether it starts with an "S"." You use the following options ( in the syntax [[ option filename ]] ( to test files: y y y -a ( to test whether a file exists -d ( to test whether a file is a directory -f ( to test whether a file is a regular file . < You use the [[ string1 < string2 ]] syntax to test if the characters in string1 comes before characters in string2 in the dictionary. The string operators test the lexigraphical order of two strings. A string that appears before a second string in the dictionary is considered "smaller" than the second string. so the code echoes the string "Bigger. Consider the following code: SMALLER=$(abc) [[ $SMALLER < bcd ]] && echo "Smaller" In this code. Consider the following code: DOTW=$(date +%A) [[ $DOTW != S* ]] && echo "Workday!" In this example." > You use the [[ string1 > string2 ]] syntax to test if the characters in string1 comes after characters in string 2 in the dictionary. and if it doesn't.

-L The [[ -L filename ]] syntax returns an exit status of 0 if the specified file exists and is a symbolic link. In addition to using options to test file attributes. A symbolic link is a directory or file name that you use to change to another directory without typing its full pathname. you can compare files using the following syntax: y y y [[ filename1 -ef filename2 ]] [[ filename1 -nt filename2 ]] [[ filename1 -ot filename2 ]] -G -L -O -S [[ filename1 -ef filename2 ]] The expression [[ filename1 -ef filename2 ]] evaluates whether two files are the same. . [[ -s new ]] && print "The file contains data" Additional file options that the Korn shell provides for testing file attributes include y y y y -G The [[ -G filename ]] command returns an exit status of 0 if the specified file exists and the group ID of the file matches the effective group ID for the current process. -O The [[ -O filename ]] syntax returns an exit status of 0if the user ID for the specified file matches the effective user ID for the current process.y y y y y -r ( to test whether a file is readable -w ( to test whether a file is writable -x ( to test whether a file is executable -s ( to test whether a file contains any data -u ( to test whether a file has a user ID bit set for it To test whether a file named "new" contains data so that you don't overwrite it if it does. -S The [[ -S filename ]] syntax returns an exit status of 0 if the specified file exists and is a socket. for example. Symbolic links can bridge file systems and link to directories. Sockets are file descriptors and obey file descriptor semantics. you use this statement.

[[ filename1 -nt filename2 ]] The syntax [[ filename1 -nt filename2 ]] checks if filename1 is newer than filename2. What statement do you think you need to use to ensure that only older files are overwritten? [[ MISSING CODE ]] && print "Overwriting older file" Options: 1. you use -eq -ne -le -ge -gt . you use the following integer operators: y y y y y -eq You use the -eq option with the syntax [[ expr1 -eq expr2 ]] to test whether expression1 is equal to expression2. 4. Question Suppose that you're writing a program that backs up files. 3. You want to back up a file named "currentfile" and to ensure that the program only overwrites files by this name that are older than the backup version to ensure that the information it contains remains up to date. for example. [[ filename1 -ot filename2 ]] The syntax [[ filename1 -ot filename2 ]] checks if filename1 is older than filename2. 2. To compare expressions involving integers. backupfile -nt currentfile currentfile -ef backupfile currentfile -ot backupfile currentfile -nt backupfile Answer You use the statement [[ currentfile -nt backupfile ]] && print "Overwriting older file" to ensure that the program will overwrite only files older than the backup version of the file. To return an appropriate message to users who enter an age of 64.

you use this code. -gt You use the -gt option with the syntax [[ expr1 -gt expr2 ]] to test whether expression1 is greater than expression2. for example. for example. To return an appropriate message to users who enter an age at or below 64. -le You use the -le option with the syntax [[ expr1 -le expr2 ]] to test whether expression1 is less than or equal to expression2. [[ $age ±ne 64 ]] && print " Your age is not equal to 64" You use this code to return an appropriate message to users who enter an age other than 64. To return an appropriate message to users who enter an age greater than 64. See if you can identify the command that you think will do this. for example.this code. [[ $age ±ge 64 ]] && print " Your age is above 64" You use this code to return an appropriate message to users who enter an age equal to or above 64. you use this code. for example. [[ $age ±ne 64 ]] && print " Your age is 64" -ne You use the -ne option with the syntax [[ expr1 -ne expr2 ]] to test whether expression1 is not equal to expression2. [[ $age ±le 64 ]] && print " Your age is below 65" -ge You use the -ge option with the syntax [[ expr1 -ge expr2 ]] to test whether expression1 is greater than or equal to expression2. . [[ $age ±gt 64 ]] && print " Your age is above 64" Question Suppose that you want to test if a file named "travel" exists.

and are slightly more versatile. you want to test that it contains data. #!/usr/local/bin/ksh if [[ -a travel ]] then print "The file if MISSING CODE then print "The else print fi else print "The file fi exists" file is not empty" "The file is empty" doesn't exist" Answer You type [[ -s travel ]] to check that the file contains data. Read more about conditional testing using the Bash shell. Question Suppose that if the file named "travel" exists. Footnote The Bash shell supports the use of single and double square brackets ([] and [[]]) for conditional testing. Double square brackets are a recently added feature.#!/usr/local/bin/ksh if MISSING CODE then Answer You use the statement [[ -a travel ]] to check if the file named "travel" exists. See if you can identify the code required to do this. The Bash shell supports the following arithmetic test options: -lt ± less than .

Option 1 is correct. Options: 1. Option 4 is incorrect. This operator will return a value of 1 if the two strings have different values. If variables X and Y have different values. [[ -a filename ]] . != = > < Answer The != string operator will cause a test condition to return a value of 0 if the strings being compared are not the same. This operator will return a value of 0 if the string on the right of the operator has a greater value than the string on the left of the operator. Option 3 is incorrect. the test shown here will evaluate as true. Question Match the options in the syntax to the description of their function. This operator will return a value of 0 if the string on the left of the operator has a greater value than the string on the right of the operator. 3. 2. as represented by a return value of 0: [[ $X != $Y ]] Option 2 is incorrect.-le ± less than or equal to -eq ± equal to -ge ± greater than or equal to -gt ± greater than -ne ± not equal to Question Which operator will return a 0 if you compare two strings with different values? Options: 1. 4.

strings. integers. This allows you to manipulate files. The [[ « ]] command is preferable because it results in fewer syntax errors. and expressions for specific conditions. Conditional statements | | Summary | Copyright © 2003 SkillSoft. the ±s option tests whether the file contains data. [[ -x filename ]] Targets: A. test. A test using the ±x option will evaluate as true if an executable permission has been set on the file. A test using the ±a option on a filename will evaluate as true if the file exists. Summary The Korn shell allows you to test strings. and strings.2. Testing conditions | | 2. Table of Contents | Top of page | | Learning objective | | 1. This syntax tests whether a file is executable Answer The ±a option tests a file's existence. All rights reserved. This syntax tests whether a file contains any data B. You can use the [ « ]. and the [[ « ]] commands to test conditional statements. or expressions by using the double ampersand (&&) or the double pipe (||) operators. This syntax tests whether a file exists C. SkillSoft and the SkillSoft logo are trademarks or registered trademarks . You can compare strings. files. and the ±x option tests that the file is executable. check file attributes and do arithmetic tests with the Korn shell. You can use compound expressions to test conditions that require the comparison of files. A test using the ±s option will evaluate as true if the file is not empty. [[ -s filename ]] 3.

You use the if then command to execute subsequent commands when a given condition is true. Flow control You use conditional statements to control the flow of code execution in UNIX shell scripts.of SkillSoft in the United States and certain other countries. Conditional statements include statements that use the if then command. You use the if then else command with this syntax. if condition then commands fi This code. for example. checks that the password that a user enters is "password01". All other logos or trademarks are the property of their respective owners. the if then else command. and the case command. the if then elif command. If it is. the conditional statement evaluates to true and the subsequent code executes to display the message "You can proceed". 1. | Print | Contents | Close | Using UNIX shell control structures Learning objective After completing this topic. #!/usr/local/bin/ksh echo "Enter password" read password if [[ $password = password01 ]] then print "You can proceed" fi The if then else command allows you to specify that one set of commands must execute if the condition is true and that another set of commands must execute if the condition is false. . you should be able to use flow control commands in shell programs. You use the if then command with this syntax.

It executes a set of commands if the first condition is true and another set of commands if a subsequent condition is true. The program will then proceed once the correct password is typed. If the condition is false ± because a user enters a password other than "password01" ± the statements after the else keyword will execute to display the message "Goodbye" and to exit.if condition then commands else commands fi In this example. the statements after the then keyword will execute if the condition for the if command evaluates to true. #!/usr/local/bin/ksh echo "Enter password" read password if [[ $password = password01 ]] then print "You can proceed" else print "Goodbye" exit fi The if then elif command allows you to specify more than one condition. If no condition evaluates to true. if condition1 then commands elif condition2 then commands elif condition then commands else commands fi In the example. the statements that follow the else keyword execute. . the elif command allows you to ask the user to re-enter a password if they typed it incorrectly.

esac Question . echo "Enter password" read password case $password in admin01 ) print "Administrator rights are assigned" .#!/usr/local/bin/ksh echo "Enter password" read password if [[ $password = password01 ]] then print "You can proceed" elif [[! $password = password01 ]] then print "Please retype password" read password if [[ $password = password01 ]] then print "You can proceed" else print "Goodbye" exit fi print "Welcome $USER" The case command can compare a single value to a number of other values. If the user input for the variable conforms to one of three options.. If the single value matches one or more specified patterns. In this case. it prints a suitable message to standard output. esac This Korn shell script illustrates the use of a simple case statement.. password01 ) print "User rights are assigned" . read01 ) print "Read rights only" . patternn) command command. pattern2) command command. The following code prompts the user to supply a value for a variable called password. the code performs the specified action.. the commands associated with the patterns will execute... case value in pattern1) command command..

MISSING CODE esac Answer You type 4 ) . See if you can type the code that adds this program as number 4 to the menu program. #!/usr/local/bin/ksh echo "Enter menu number" read menu 1 ) ... 3 ) . 3 ) . #!/usr/local/bin/ksh echo "Enter menu number" read menu MISSING CODE 1 ) ./bookings .Suppose that you are writing a menu program that will load a certain program when the user enters a specific number./flights ./customers to create another menu item that will execute the program named "customers".. Question Suppose that you want to add another menu item to run a new program named "customers"./bookings . 2 ) ./travelpackage . esac Answer You type case $menu in to complete the case command that allows the user to type a number to execute a program. See if you can complete the code that allows the user to type a number to execute a program../flights . 2 ) .../travelpackage . Question .

Option 2 is correct.Which conditional statement allows you to execute one set of commands if a condition is true. and "airplane. such as "a". This statement is used to execute code based on whether one or more patterns match a particular value. A word is a piece of a line that the shell has broken up. 2. This statement is useful if you need to use additional conditions after the elif syntax. This statement executes code after then if the specified condition is met. Option 3 is incorrect. Introducing and using loops Loops are recursive code that executes repeatedly until a specific condition is met." The commands execute after the do statement and the done statement ends the loop. in which case they continue to execute indefinitely. and after else if it isn't. Loops can be infinite. "apple". so you need to be careful when specifying conditions. 4. You use the for command with this syntax to execute commands a specific number of times. This statement only executes code if a condition evaluates as true. Option 4 is incorrect. 2. you use an if then else fi statement. 3. This process is called iterative execution. You use loops to perform various tasks in a sequence and to automate system administration. and another if it is false? Options: 1. if then fi if then else fi if then elif fi case esac Answer To specify the execution of code based on whether a single condition is true or false. Option 1 is incorrect. for variable in word1 word 2 « wordn do .

you can use this program to display a loop number and a loop value for each iteration of the loop. as in this code.commands done For example. you use the syntax shown here. . while condition1 do commands done . Loop 1: x=a Loop 2: x=b Loop 3: x=c You can assign parameters to a loop dynamically. #!/usr/local/bin/ksh integer loopnum=1 for x in a b c do print "Loop $loopnum: x=$x" (( loopnum+=1 )) done This is the output of the script. which you can use to make one or more files executable./mkexe filename1 filename2 « filenamen A loop that uses the while command continues to execute until a specified condition is true. #!/usr/local/bin/ksh for FILE do chmod 700 $FILE print "$FILE is executable" done If you save a file named "exe" and you have a script named "sample" then you can make the sample file executable by typing the command ./mkexe sample To make one or more files that you own executable.

What do you think the output of this script will be? #!/usr/local/bin/ksh integer y=3 while (( y < 5 )) do print "The value of y is $y" (( y = y + 1 )) done Options: . Tracking the value of variables is an important part of debugging a script. Syntax errors are usually fairly easy to detect. In other words. but logical errors may require monitoring how a variable changes during the course of a script's execution. to create directories using the while command you use the code shown here. the commands continue to execute until condition1 returns a zero exit status. until condition1 do commands done Question Suppose that you want to debug a Korn shell script that another person wrote. For example.If the exit status of the conditional statement is zero the commands between do and done are executed. #!/usr/local/bin/ksh echo "What is the name of the directory" read directory echo "How many directories do you want to make?" read dirnumber count = 1 while [[ $count -le $dirnumber ]] do mkdir $directory$count (( count+=1 )) done A loop that uses the until command continues to execute while a specified condition continues to evaluate to false.

The output is then as follows: The value of y is 3 The value of y is 4 Option 1 is incorrect. Question Which statements correctly describe the characteristics of loops? Options: 1. before incrementing it. The shell checks the logic of loops to prevent code being executed an infinite number of times 2. The statement that prints the value of y is executed before y is incremented. Option 4 is incorrect.1. so the first iteration of the loop prints the initial value of y. The value of y is 2 The value of y is 3 The value of y is 4 2. Option 3 is incorrect. The value of y is 3 The value of y is 4 The value of y is 5 4. The second iteration prints the new value. Option 2 is correct. Loops execute code while a specified condition is met. which is 3. You use the test command with the while loop Answer . The first iteration of the loop prints the current value of y. Only two iterations of the loop take place. Although y having a value of 2 meets the conditions of the test on which the loops is performed. The value of y is 3 The value of y is 4 3. the first line of code assigns a value of 3 to y. The value of y is 4 Answer The initial value of y is 3 and the loop executes until the value of y is less than 5. You must specify the number of parameters that you intend to pass to a for loop 4. and then increments it by 1. 4. or a specified number of times 3. because after the second iteration the condition on which the loop takes place is no longer true.

You can use the test command to specify a condition. and you specify a condtion for which while loops take place. Flow control | | 2. which while it holds true. Table of Contents | Top of page | | Learning objective | | 1. You can dynamically assign parameters to the for loop. You supply parameters to the for loop on which code is executed. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. Option 4 is correct. or until a condition is met. Option 2 is correct. A loop is a set of commands that executes ± or iterates ± repeatedly. will cause a while loop to execute. either while or until a specific condition is met or for a specified number of iterations. Loops can be infinite. the if then else command. If the condition isn't met. Summary To control the flow of execution in UNIX shell scripts.Loops execute code for each argument supplied. All other logos or trademarks are the property of their respective owners. | Print | Contents | Close | Using flow control in a UNIX shell program . you use conditional statements. Option 1 is incorrect. Introducing and using loops | | Summary | Copyright © 2003 SkillSoft. and the case command. You use the test command with the while loop. the loop will be infinite. All rights reserved. so you should take care when specifying conditions on which they take place. These include statements that use the if then command. you can use command-line arguments to assign them. For example. Option 3 is incorrect. the if then elif command.

the script must terminate. First. the script must check to see if any files have been modified in a specified directory. If not files have been modified. you should be able to use conditional expressions and flow control in a shell program. See if you can type the code indicating the function name and the start of the function.Learning objective After completing this topic. If files have been modified. Question Let's say that you want to write a function called check_date that determines whether the current date falls on a weekend. it must e-mail the user. Task 1: Writing a function Suppose that you want to create a script that will notify a user by e-mail if specific files have been modified during week days. the script must check the date. you're required to use conditional expressions and flow control in a shell program. To do this. you need to write a Korn shell script that exits if the date is not a week day. #!/usr/local/bin/ksh #===================== # Function" Check if today is a weekday #====================== MISSING CODE today=$(date '+%A') #====================== check_date . Exercise overview In this exercise. If it is a week day. 1. This involves the following tasks: y y writing a function writing the main script 2.

Question You want to ensure that the program runs on weekdays See if you can complete the code that allows you to provide an alternative condition for the if statement.Answer You either enter function check_date { or check_date { to begin the function definition. See if you can supply the operator that will exit the shell script on Saturdays and Sundays. #!/usr/local/bin/ksh #===================== # Function" Check if today is a weekday #====================== function check_date { today=$(date '+%A') . Question You want to ensure that only files modified on weekdays are mailed to the user. #!/usr/local/bin/ksh #================== #Function "Check if today is a weekday #====================== function today=$(date '+%A') if [[$today == Saturday MISSING CODE $today == Sunday ]] then return=false fi } #======================= check_date Answer The operator that will exit the shell script on Saturdays and Sundays is ||.

in this case. Question The condition you include needs to evaluate to true on weekdays so that the program continues to run on these days. See if you can complete the code that allows this. is else. Task 2: Using conditional statements . #!/usr/local/bin/ksh #===================== # Function" Check if today is a weekday #====================== function check_date { today=$(date '+%A') if [[ $today == Saturday || $today == Sunday ]] then return=false else print "Today is a weekday" MISSING CODE } #======================= check_date Answer The code that allows a true return value is else return=true 3.if [[ $today == Saturday || $today == Sunday ]] then return=false MISSING CODE fi } #======================= check_date Answer The code that allows an alternative condition.

Question You want to print the list of any files that have been modified using the cat command. return=false check_date if [[ $return == true ]] then print "Finding out if files were modified today" MISSING CODE Answer You type modify to call the modify function. See if you can complete the code that allows you to call the modify function. .After writing the check_date function to check if the current day is a weekday. #================ #Function: checks what files are modified today #================ function modify { find /home/vincep ±ctime 1 > logfile if [[ ! ±s logfile ]] then print "No files were modified" modified=false else print "Files were modified" modified=true fi } Question You now want to complete the code so that the program checks to see if any files have been modified in a directory and then outputs any files that have been modified. you also write this modify function to check if any files have been modified in the last 24 hours. Choose the flow control statements that will print out the modified files.

return=false check_date if [[ $return == true ]] then print "Finding out if files were modified today" modify MISSING CODE fi Options: 1. if [[ $modified == true ]] then print "The modified files:" cat logfile fi 3. The use of the ! operator on the first line means that the condition evaluates as false if files are modified. whereas you need it to evaluate as true. . while [[ $modified == false ]] do print "The modified files:" cat logfile done 4. while [[ $modified == true ]] do print "The modified files:" cat logfile done Answer The missing code is if [[ $modified == true ]] then print "The modified files:" cat logfile fi Option 1 is incorrect. if [[ ! $modified == true ]] then print "The modified files:" cat logfile fi 2.

All other logos or trademarks are the property of their respective owners. The loop executes if files are not modified. If this test evaluates as true. the rest of the if fi statement is executed. Option 3 is incorrect. this loop will be infinite. All rights reserved. The shell script exits if it is a weekend or if no files have been modified. To avoid infinite looping if the condition is met. The shell script then checks if the files in a directory have been modified and outputs these files with the cat command. The first line tests that files have been modified. Exercise overview | | 2. Task 2: Using conditional statements | Copyright © 2003 SkillSoft. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. Option 4 is incorrect. return=false check_date if [[ $return == true ]] then print "Finding out if files were modified today" modify if [[ $modified == true ]] then print "The modified files:" cat logfile fi fi Table of Contents | Top of page | | Learning objective | | 1. Task 1: Writing a function | | 3. in which case there will be nothing to print. Also. printing a list of the modified statement accompanied by a message. if the condition is true. you need to include the following command at the end of the code that is executed by the loop: modified=false You have now created a function that tests whether the current day is a weekday. | Print | Contents | Close | .Option 2 is correct.

organizing shell scripts Functions organize shell scripts into modular pieces of code that are easier to develop and maintain than separate commands. Functions improve shell programming by y y increasing the speed of code execution organizing shell scripts increasing the speed of code execution Functions execute faster than scripts because they are loaded in memory. the shell doesn't need to read them from disk each time a script references them. . For example. Functions can be self-contained or contained in shell scripts. 1. you can create a function to print an error message whenever specific errors occur. Introducing functions A function is a set of commands grouped together and called by the same name that accepts a number of arguments as input and can return a value. they can be stored in memory and executed at the command line. As a result. they need to be called in the main body of the shell script. When functions are self-contained. For example. function md { mkdir $1 && 'cd' $1 } When functions are contained within shell scripts. you should be able to use functions to improve the efficiency of program code. Functions also consolidate redundant sequences of commands.Functions in UNIX shell programming Learning objective After completing this topic. this self-contained function will create a directory and then access that directory.

#!/usr/local/bin/ksh x=1 function myfunc { x=3 typeset y=4 print "In local print "In local } myfunc print "Outside local print "Outside local function x is $x" function y is $y" function x is $x" function y is $y" Note You can declare functions using the Portable Operating System Interface (POSIX) format shown here to maintain compatibility with the Bash shell. This reduces the need for extra code. recursion is possible. #!/usr/local/bin/ksh function get_time { TIME=$(date +%m/%d/%y-%H:%M:%S) printf "$TIME\n" } get_time You can declare a local variable in a function using the typeset command. #!/usr/local/bin/ksh function quit { exit } print "Hello world" quit This code uses a get_time function to return the current time in the format that shell scripts require. All the other function variables are inherited and shared by the Korn shell script. Because functions can have local variables. . Functions that have this format cannot contain local variables.function name { commands } A simple function named quit is called from the main shell program to quit after printing "Hello world".

2. *) print "Non-numeric input. 4. esac } get_number print "The number is $num" integer answer=$num*5 print "Five times number is $answer" Question Why do functions improve the performance of shell programs? Options: 1. 3. This allows you to pass variables to a function and to obtain a return value from the function. The return command uses the syntax return variable You can use this script to ensure that the user's input is an integer value and then to return this value for further calculation.. #!/usr/local/bin/ksh function get_number { print "Input a number between 1 and 9" read num case $num in +([0-9])) print "Input is numeric" .. try again" .The syntax for doing this is function_name() { commands } You can use the return command to pass an exit value from a function to the invoking Korn or Bash shell script. Because they allow you to reuse code Because they are loaded into memory Because they use control flow structures Because they use local variables Answer .

and there is no significant performance gain associated with either. from where it is executed whenever a script calls it. You can use the return command to specify a return value for a function. functions accept one or more arguments. Functions can use local or global variables. Question Identify the true statements concerning functions. Option 2 is correct. Options: 1. 3. 2. as long as it is before they are first called. While functions do allow you to reuse code. Functions always return the exit status of their last command Functions can be defined within a shell script You can pass arguments to a function You can read self-contained functions directly into memory Answer Functions can be defined within a shell script or read directly into memory. 2. Option 1 is incorrect. Option 4 is incorrect. You can store a function in an ordinary text file and use the . Option 3 is incorrect. Option 1 is incorrect. Usually. Option 3 is correct. Uses of functions . Option 4 is correct. This is more efficient than reading the code from disk. It is common for a function to accept arguments. Functions can be defined at any point in a shell script. 4. When a function is first declared it is copied into memory. Functions don't have to include control flow stuctures. Option 2 is correct.Functions improve the performance of shell programs because they are loaded into memory. it is the fact that the function's code is copied into memory that improves performance. which are supplied after the function name when you call the function. command to read it into memory.

*) print "Non-numeric input. try again" . You need to read these functions into memory so that you can execute them from the command line.. Because functions have local variables. you can use a function to verify that a user inputs the correct data in response to a prompt. esac } get_number print "The number is $num" integer answer=$num*5 print "Five times number is $answer" . a self-contained function ± named get_time ± outputs the time in a specific format. they allow recursion. In the following example. You normally use functions for commands that are invoked often.Functions are a form of command that can be y y self-contained used within shell scripts self-contained You use self-contained functions to execute a number of commands from the shell.. Functions can accept arguments and then return values after processing the data. For example. function get_time { TIME=$(date +%m/%d/%y-%H:%M:%S) printf "$TIME\n" } used within shell scripts You use functions within scripts to organize data. as illustrated in the following code: #!/usr/local/bin/ksh function get_number { print "Input a number between 1 and 9" read num case $num in +([0-9])) print "Input is numeric" .

When it finds the appropriate file. you type . a script calls a discipline function when it accesses the variable associated with the function. You generally autoload functions that are not invoked frequently. command to read self-contained functions into memory. the shell reads in the functions when they are first invoked and keeps them in memory. you use this syntax. rather than reading them in each time they are invoked. you first need to set the FPATH variable with the name of the directory that stores it.You use the . function get_number { print "Enter a number from 1-9" read num case $num in ([0-9]) ) print "Thanks" * ) print "Try again!" esac } typeset ±fx get_number You can autoload functions to improve performance. error_message. to read in the function error_message. For example. Once you read a function in. For example this command will export the get_number function. To autoload a function. Rather. it reads and executes it in the current environment. To autoload a function. . typeset ±fu function_name Discipline functions manipulate variables. you can invoke it from a shell script using the syntax function shell_script In the Korn shell you can export functions using the typeset ±fx functionname command. In this case. You can define these functions. The shell searches each directory in the FPATH variable from left to right for a filename that matches the name of the function. although you don't call them specifically in shell scripts.

Thanks 6 squared is 36 2. Question Suppose that you have written a shell script to ensure that users enter an integer value for use in a calculation.. esac } while [ $num != [1-9] ] do get_number done ((square=num*num)) print "$num squared is: $square" Options: 1.unset when the variable time is accessed. or unset respectively.get. time. Try again! 6 squared is 36 Answer The output of the script will be as follows: Try again! Thanks 6 squared is 36 . the shell calls the discipline functions time.For example. and time. Try again! Thanks 6 squared is 36 4. * ) print "Try again!" . What do you think the output of this script ± excluding interactive prompts ± will be if a user first enters a text value and then the value 6? #!/usr/local/bin/ksh function get_number { print "Enter a number from 1-9" read num case $num in ([1-9]) ) print "Thanks" . Try again! 3..set. set.

All other logos or trademarks are the property of their respective owners. Uses of functions | | Summary | Copyright © 2003 SkillSoft. Option 3 is correct. The user first enters text. Table of Contents | Top of page | | Learning objective | | 1. Once the user has supplied a valid value for the num variable. and the code that prints the square of the num variable is executed. The get_number function provides feedback when a suitable variable has been entered. The while loop ensures that the get_number function is executed repeatedly until the user supplies a value between 1 and 9. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. Introducing functions | | 2. which matches the "catch-all" pattern in the case statement: *) print "Try again!" Option 2 is incorrect. the while loop exits because its condition is met. You can read a function in and then invoke it from the shell. Functions improve shell programming by executing faster than separate commands and by organizing shell scripts into manageable modules of code. After autoloading a function. To allow the autoloading of functions.Option 1 is incorrect. You declare functions using the Portable Operating System Interface (POSIX) format to maintain compatibility with the Bash shell. Summary Functions can be self-contained or contained in shell scripts. the shell reads it in when it is invoked rather than each time a Korn shell script invokes it. All rights reserved. | Print | Contents | Close | Using I/O in UNIX shell programs . you need to set the FPATH variable with the pathnames to files for autoloading functions. Option 4 is incorrect.

standard output The standard output file provides a means for the program to output data. which are y y y 0. By default. standard error The standard error file is where the program reports any errors encountered during execution. 1. to identify standard error (stderr) If you want input to go to standard error. you use the following syntax: input 2>standard_error_output You can control program input/output (I/O) ± including the source that a program uses for input and where it sends output and standard error ± using redirection.Learning objective After completing this topic. You need to use file descriptors with some redirectors ± such as the exec command. These files exist for as long as the program runs. the standard output goes to the terminal display screen. to identify standard output (stdout) 2. . to identify standard input (stdin) 1. By default. Understanding I/O control Each program you run from the shell opens files that provide the primary means of communication between it and other processes or programs. you should be able to use the UNIX I/O system in shell programs. which opens specified files. The Korn shell automatically assigns the most common file descriptors. the standard error goes to the terminal display. By default. The files that active programs open are y y y standard input standard output standard error standard input The standard input file provides a way to send data to a program. the standard input is read from the terminal keyboard.

EOF (end-offile). What command do you think transfers the user's response to memory so that the input can be used for processing? Options: 1. You use a "here" document to redirect multiple lines from standard input to a command. to append standard output to a file >|. you redirect the standard input using a marker string ( most commonly. line by line.You can use the following redirection commands: y y y y y >. until it encounters the specified word ± in this case. and Mary. the here document feeds instructions to the mail command. to redirect standard input from a file <>. in a script that sends e-mail to a list of users named Terry. Question You can include user interactivity in a shell script. Larry. you can include the instruction <text1 in a shell command to instruct the shell to read input from a file called text1 instead of from the terminal keyboard. The shell reads the input to the command until it encounters a line that contains only the marker string. To do this. For instance. In the example cat > script4 << EOF. All the lines it has read ± except for the marker string line ± are then fed to the command as its standard input. The syntax for a here document is command<<word For instance. the shell reads standard input for cat until it reaches a line containing only the string EOF. END. the shell sends the content of the password file to the more command for display on the screen. echo 2. print . to redirect standard error You can instruct the shell to use the content of a file as input. It then creates a file called script#4. In the example more < /etc/passwd. to overwrite an existing standard output file even if noclobber is enabled <. to redirect standard output to a file >>.

The print command displays the content of a specified string ± the prompt you want the user to respond to ± on screen. -r The -r option forces the shell not to interpret the backslash (\) as a line continuation character. You can modify its behavior using the following options: y y y y y y y -n -p -r -R -s -un -p -r -s -un .3. You can modify the behavior of the read command using the following options: y y y y -p The -p option instructs the shell to read an input line from a coprocess. quote 4. read Answer The read command transfers the user's response to memory so that it can be used for processing. -s The -s option causes the shell to save a copy of an input line in the command history file. -un The -un option causes the shell to read a specified input line from the specified file descriptor.

Note If the file named ls. To prevent this.out creates a file containing the output ± in this case a listing of the /tmp directory ± of the ls command into a new file called ls. -n The -n option prevents the shell from adding an ending newline to the output. the old version will be overwritten. -un The -un option causes the shell to redirect arguments to the specified file descriptor.option causes the shell to interpret all strings following the hyphen as an argument. -p The -p option causes the shell to redirect arguments to a coprocess. You can direct the flow of output from a command to a file instead of to the default terminal screen. even when the string itself begins with a hyphen. -s The -s option causes the shell to redirect specified arguments to the history file.out. -r The -r option causes the shell to ignore the backslash (\) escape conventions. For instance. Instead of displaying errors on screen. as well as preventing it from interpreting arguments preceded by a hyphen as options.The . For instance.out already exists. -R The -R option causes the shell to ignore the backslash (\) escape conventions. place the results in a file called prog_errors. in the Korn shell you could sort the /etc/passwd file. Options: . you can append content to the end of a file using the >> command. and trap any errors in a file called log_errors using the command sort < /etc/passwd > prog_errors 2> log_errors Question Match the redirection operator to its specific function. the code ls /tmp > ~/ls. you can redirect a program's standard error to a file or command.

>| Targets: A.txt Question Which option for the read command do you use if you don't want the backslash (\) to be interpreted as a special character when supplied as input? Options: 1. you use the >| operator. Appends standard output to an existing file B.txt with this command: ls >> dirlist.txt with this command: ls >| dirlist. Redirects standard output to a file. If the file already exists and you want to overwrite it despite the noclobber option being set.txt You can redirect the output from the ls command to a file named dirlist. . You can append the output from the ls command to a file named dirlist. >> 2. > 3. 4. 2. overwriting an existing file even if the noclobber option is set Answer The > redirects standard output to a file. Redirects standard output to a file C. 3. You append standard output to a file with the >> operator.txt Even if the noclobber option is set. -p -r -s -u Answer You use the ±r option to prevent the backslash (\) being interpreted as a special character in input supplied by the read command. you can redirect standard ouptut to overwrite an existing file called dirlist.1.txt with this command: ls > dirlist.

The read ±p option is used to accept input from a co-process spawned using the |& operator. Option 2 is correct. A user may need to transfer a file to an anonymous FTP site ± which doesn't require the user's username or password ± or to a secure site ± which does require authentication. Programming with I/O control Let's say that you want to write a program to automate file transfer across a network for users. the statement will create two new variables ± FTPLOGIN and PASSWD. you start interaction with the user by printing the question Do you want to perform an anonymous ftp [y/n]: to the screen. The read ±u option is used to specify the file descriptor used to provide input. you decide to divide the program into two logical sections. . During planning. If the option is not inserted. Option 4 is incorrect.Option 1 is incorrect. as in read ±u 0. The first section will gather user data ( such as a user's username and password ( and the second section will use this data to connect to a server and transfer local files to the server. 2. the backslash causes special characters to be treated as literals. Using an echo command. The value of FTPLOGIN will be "anonymous" and PASSWD won't contain a value. which the program then reads into memory as the value of the ANON variable. The default is standard input. The loop exits only when the user enters a correct value. If the value of ANON is yes. To cater for the two possible values of the ANON variable ± yes or no ± you need to use an if « else statement to create two conditions. To ensure that the value that a user enters is either y or n. The read ±s option will cause input to be saved in the command history file. So your code first needs to determine how the user intends to transfer a file. Option 3 is incorrect. You then use the read command to create a new variable called ANON to place the user's reply ± yes or no ± in memory. Each time a user enters a value other than y or n. the commands in the loop execute to prompt the user for a correct response. you create an echo « read loop inside a while « do statement.

please: " read ANON done if [[ $ANON != y ]] then FTPLOGIN=anonymous PASSWD=" " else echo "Enter the username to use: " read FTPLOGIN echo "Enter the password to use: " read PASSWD fi Question If the FTP session that a user requests is not anonymous. 4. the user needs to provide authentication details to log in to the remote server. Once the program has obtained user authentication details. Which variables do you think you need to specify in the statements? Options: 1. .echo "Do you want to perform an anonymous ftp [y/n]: read ANON while [[ $ANON != y && $ANON != n ]] do echo "Enter y or n. 3. 2. ANON FTPLOGIN PASSWD A new variable to store the user's login details Answer You need to specify the FTPLOGIN and PASSWD variables to retrieve the user's username and password. it needs to prompt the user to supply the address of the server to which a file is to be transferred and the name and location of this file. You decide to use two echo « read statements to allow the user to supply these values.

you need to specify the ftp commands that the user's local computer must use to make the actual file transfer. in which you create two new variables ± FTPSERVER and FILE ± to contain the new information. you write a here document.2. ( ftp -n <<. you use two print « read statements.2. which terminates itself and the FTP program when it reaches the END marker. To do this. You follow the screen prompts and the file is transferred without error.To make the program do this.100.END open $FTPSERVER quote USER $FTPLOGIN quote PASS $PASSWD binary cd /home/gregl put $FILE END ) Let's say that you want to test your program by anonymously sending a file called case.sh to a server at the IP address 190./ftp. please: " read ANON done if [[ $ANON != y ]] then FTPLOGIN=anonymous PASSWD=" " print "Enter the address of the FTP server: " read FTPSERVER print "Enter the file to transfer: " read FILE To allow the program to establish an FTP session with a server. echo "Do you want to perform an anonymous ftp [y/n]: read ANON while [[ $ANON != y && $ANON != n ]] do echo "Enter y or n.sh Do you want to perform an anonymous ftp [y/n]: . $ .

not to receive input. Option 1 is incorrect. Option 4 is incorrect. Option 3 is incorrect. 2. print "Enter the account name: " Missing_code NAME Options: 1. These files are standard input.100.y Enter the address of the FTP server: 190. typeset ±x is used to export a variable.2. The read command will provide a prompt.2 Enter the file to transfer: case. You can direct the flow of output and errors from a command to a file instead of to the default terminal screen.sh $ Question You are writing a script to automate the process of adding a user account to the system. . You need to use file descriptors with some redirectors. Identify the command that completes the code that obtains an account name from standard input. Option 2 is correct. The echo command will merely print the string NAME to the screen. echo read typeset -x << Answer You use the read command to obtain the account name from standard input. The << operator is used to open a here document. Summary Programs that run from the shell open files that provide the primary means of communication between it and other processes or programs. and standard error. and input at the prompt will be assigned to the NAME variable. 4. standard output. 3.

you can create a program that automates file transfer across a network for users. Introducing the select command The select command allows you to create a simple menu that users can use to interact with a program. For example. you should be able to create user menus with the select command and use them in shell programs. You specify a select command using the syntax shown here. you need to supply a list of menu item names. Note The select command is available only in the Korn shell and version 1. All rights reserved. In the syntax. The command will associate the names you specify with the commands contained in the loop. The menu contains numbered items and displays a prompt message. All other logos or trademarks are the property of their respective owners. Table of Contents | Top of page | | Learning objective | | 1. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. 1. followed by a do « done statement loop. | Print | Contents | Close | Using menus in UNIX shell programs Learning objective After completing this topic. Programming with I/O control | | Summary | Copyright © 2003 SkillSoft.14 and later of the Bash shell. .You can write programs that use input/output (I/O) control. This program gathers data and then uses this data to connect to a server and then transfer local files to the server. Understanding I/O control | | 2.

run a text editor. return. or EOF marker 2. or EOF marker Stores the selected option in a built-in variable named REPLY Answer Correct ranking Option B D A C Description Prompts the user for a number Stores the selected option in a built-in variable named REPLY Executes the statements in the body of the command Breaks on encountering a break. return.select variable in name1 name2 « namen do commands done Question The select command generates a menu containing each specified item in a numbered list. Whenever a shell displays a menu prompt. You decide to change the default menu prompt ( which is #?. or exit the script. Options Option A B C D Description Executes the statements in the body of the command Prompts the user for a number Breaks on encountering a break. exit. meaning "which number?" ( to . exit. See if you can place the steps that the select command performs when a user selects a menu item in the correct sequence. it uses a default prompt character stored in a shell variable named PS3. Creating menus Let's say that you want to write a shell script that allows users to view the files in a directory.

its corresponding value is recorded in the user-defined OPTION variable and stored in the built-in REPLY variable. in the order in which they are to appear on screen. In this case. and "Exit". What command do you think you can use to insert dummy text for these options? Options: 1. #!/usr/local/bin/ksh PS3="Select an option [1-3]> " You name the menu items "Show files". You do this using an if . To do this. you first specify that if the user chooses the third menu option ( the Exit option for quitting the menu ( the select command will execute the exit command. #!/usr/local/bin/ksh PS3="Select an option [1-3]> " select OPTION in "Show files" "Run editor" "Exit" The do « done statement in the select command needs to specify actions that correspond to a user's selection of each of the three specified menu items. When the user selects an option. 3. echo read select quit . #!/usr/local/bin/ksh PS3="Select an option [1-3]> " select OPTION in "Show files" "Run editor" "Exit" do if [[ $REPLY = 3 ]] then exit Question Let's say that you want to test the menu at this point before adding functionality to the first two menu items.a new prompt that you specify. you set the PS3 variable to the text you want to appear as the prompt. 2. else statement. 4. "Run editor"...

instead of an if « else statement. To test the code at this point ± without adding functionality for options 1 and 2 ( you add an echo statement that is printed if a user selects any item other than the third menu item.sh Show files Run editor Exit Select an option [1-3]> You chose to Show files Select an option [1-3]> The example here shows a dummy menu generated by a select command that uses the case command to structure the menus. $ . When you use the case command. it generates a menu with labeled options and the changed prompt text you've specified.Answer You can use echo statements to print dummy option text to test the functionality of the menu. you need to number the menu items manually with . $ ./select. This returns the message "You chose to Show files" and returns to the menu.sh 1) Show files 2) Run editor 3) Exit Select an option [1-3]> Let's say that you test the menu by selecting option 1. #!/usr/local/bin/ksh PS3="Select an option [1-3]> " select OPTION in "Show files" "Run editor" "Exit" do if [[ $REPLY = 3 ]] then exit else echo "You chose to $OPTION" fi done When you execute the select command./select.

..sh 1. #!/usr/local/bin/ksh echo "1. 3 ) echo "Do action 3" . and select command input is stored in the REPLY variable. Options: 1. Menu item three Choose an option [1-3] Question Identify the true statements about the select command.).. esac The output of the dummy menu using the case command is shown here. 2 ) echo "Do action 2" . The case command can be used instead of if then else statements to execute code based on the user's menu selection. . The select command uses the REPLY variable to store user input Answer The PS3 variable determines the prompt used by the select command. Menu item one" echo "2. The select and case commands are often combined. The prompt used by the select command is determined by the PS3 built-in variable 2. $ . Option 1 is correct. The shell's interactive prompt is determined by the PS3 variable. Menu item two" echo "3. Menu item one 2. Menu item two 3.. Menu item three" echo "Choose an option [1-3]" read MENUITEM case $MENUITEM in 1 ) echo "Do action 1" . The Korn shell default is #? Option 2 is correct. The select command can be combined with the case command 3.echo statements and you need to terminate each command line with a double semicolon (./case. The select command is available in the Korn and C shells 4.

| Print | Contents | Close | Writing a UNIX shell program using I/O commands Learning objective After completing this topic. All other logos or trademarks are the property of their respective owners. The select command presents the user with a numbered menu and a prompt. Table of Contents | Top of page | | Learning objective | | 1. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All rights reserved. . Summary You can use the select command in scripts to create basic menus. you're required to create a shell script that generates a simple menu. The select command is supported by the Korn shell and recent versions of the Bash shell.Option 3 is incorrect. Introducing the select command | | 2. Both the case and select commands allow you to specify behavior based on the value of a variable. Option 4 is correct. you should be able to write an interactive program that makes use of standard input and output. The value entered by the user is stored in the REPLY variable. The case command provides similar functionality. Creating menus | | Summary | Copyright © 2003 SkillSoft. but not the C shell. but is more globally applicable. Exercise overview In this exercise.14 and later of the Bash shell. The select command is available in the Korn shell and in version 1.

Task 2: Adding functionality to options ." See if you can type the code that will change the prompt. $ . Step 2 of 2 See if you can type the command that will generate a menu. or quit the program using a simple menu.This involves the following tasks: y y specifying the menu items adding functionality to the menu Task 1: Specifying menu items Let's say that you want to create a program that allows users to view files in the current directory. #!/usr/local/bin/ksh# MISSING CODE "Choose a menu item [1-3]>" Result You enter PS3= to change the prompt text. #!/usr/local/bin/ksh# PS3="Choose a menu item [1-3]>" MISSING CODE ITEM in "View files" "Launch Editor" "Quit" Result You enter the select command to generate a menu./editor.sh View files Launch Editor Quit Choose a menu item [1-3]> Step 1 of 2 Let's say that you want to specify the menu prompt "Choose a menu item [1-3]>. edit a specified file.

Using the REPLY variable.Let's say that you now want to specify the commands that the select command must call when a user selects one of the menu items. 3. reduces the likelihood of typographical errors. so you need to use the $REPLY syntax to expand the variable. The ITEM variable needs to be expanded using the $ITEM syntax. Option 1 is incorrect. which contains a number assigned to each item in the menu that is created by the select command. 2. The case command executes code based upon the value of a variable ± in this case the REPLY variable returned by the select command. REPLY is a variable returned by the select command. Although this is a possible solution. Option 2 is correct. #!/usr/local/bin/ksh# PS3="Choose a menu item [1-3]>" select ITEM in "View files" "Launch Editor" "Quit" do Step 1 of 4 Choose the most appropriate code to start structuring the menu. Option 4 is incorrect. 4. it is more efficient to use the REPLY variable. Step 2 of 4 . case case case case REPLY in $REPLY in ITEM in $ITEM in Result You enter case $REPLY in to specify the menu structure. #!/usr/local/bin/ksh# PS3="Choose a menu item [1-3]>" select ITEM in "View files" "Launch Editor" "Quit" do MISSING CODE Options: 1. Option 3 is incorrect. it requires you to specify each possible value for the ITEM variable listed in the select command. Furthermore.

#!/usr/local/bin/ksh# PS3="Choose a menu item [1-3]>" select ITEM in "View files" "Launch Editor" "Quit" do case $REPLY in MISSING CODE Options: 1. Command substitution is used to insert the output into the string that is sent to standard output by the echo command. Option 2 is incorrect. Step 3 of 4 Choose the code that you think will specify that the second menu item is to load a specified file in the vi editor. Option 3 is incorrect. 3.Choose the code that you think will retrieve a listing of the current directory if a user selects the first menu item. 1) echo "The current directory is (pwd)" ls .. 1) echo "The current directory is $(pwd)" ls break .. To perform command substitution. . 1) echo "The current directory is $(pwd)" ls . The pwd command provides the name of the current directory as output. Option 1 is correct. The break command will exit the case loop. causing the program to end once the user has viewed the contents of the current directory. and will allow to then choose other menu options.. the brackets that contain the command must be preceded by the $ special character. Result The code that will retrieve a listing of the current directory is shown here: 1) echo "The current directory is $(pwd)" ls . The ls command then lists the contents of the current directory. 2..

Option 1 is incorrect. you need to perform variable expansion using the $FILE syntax. 2) echo "Name the file to edit" read FILE vi $FILE . 2. The read command allows the FILE variable to be set using standard input. The 2) denotes that the subsequent code is executed if $REPLY=2. To achieve the desired result of expanding the FILE variable set using the read command. MISSING CODE Options: 1. Option 2 is correct. Result The code that will load a specified file in the vi editor is shown here: 2) echo "Name the file to edit" read FILE vi $FILE . The echo command provides a prompt. This command will open the vi editor with a file named FILE in the edit buffer. . the value the FILE variable is used as an argument to the vi editor..#!/usr/local/bin/ksh# PS3="Choose a menu item [1-3]>" select ITEM in "View files" "Launch Editor" "Quit" do case $REPLY in 1) echo "The current directory is $(pwd) ls ... 2) echo "Name the file to edit" read $FILE vi FILE . Step 4 of 4 Choose the code that you think will exit the menu if a user selects the third menu item. Once it has been set..

or for loop. Each case statement must end with two semicolons. Option 1 is incorrect. When you have specified the functionality for each menu item.. Result The code that will exit the menu if a user selects the third menu item is 3) break . you end the case and do commands and print a statement to screen. Option 3 is correct. 3. This code will simply result in nothing being executed when the third option is selected ± but the loop will not be exited and the user will be prompted to choose a menu item again. MISSING CODE Options: 1..#!/usr/local/bin/ksh# PS3="Choose a menu item [1-3]>" select ITEM in "View files" "Launch Editor" "Quit" do case $REPLY in 1) echo "The current directory is $(pwd) ls . while. 3 break . #!/usr/local/bin/ksh PS3="Choose a menu item [1-3]>" select ITEM in "View files"\ "Launch Editor"\ . 3) . The break command is used to exit a case. not one. Option 2 is incorrect. 2) echo "Name the file to edit" read FILE vi $FILE . crashing the program.. This code will result in a syntax error. 2... 3) break .

and indentation. esac done Table of Contents | Top of page | | Learning objective | | Exercise overview | | Task 1: Specifying menu items | | Task 2: Adding functionality to options | Copyright © 2003 SkillSoft.. white space. it's a good idea to lay them out so that human readers can read them easily. Introduction In addition to ensuring that your shell scripts contain accurate code.. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All other logos or trademarks are the property of their respective owners. All rights reserved. | Print | Contents | Writing legible UNIX shell scripts Abstract This article describes recommended practices for writing human-readable shell scripts. including the use of comments.. . 2) echo "Name the file to edit>" read FILE vi $FILE . 3) break ."Quit" do case $REPLY in 1) echo "The current directory is $(pwd) ls .

This may require that names be quite long. you could call it customer_name. Although comments aren't essential to the functioning of a script.data function. for example. for example. you can add a comment that explains its function.customer.data ± without causing any confusion. A function that reads customer data could be read. For example.flight. it becomes much easier for readers to figure out what's going on in a script. you need a variable to contain the name of a customer. For example. and they allow other shell programmers to read and understand your script. and you can give meaningful names to variables and functions so that the reader can understand their purposes.customer. so they're a good way to build names that contain multiple words. This comment needs to explain the general purpose and structure of the script. an appropriate comment might be # This script obtains data about one or more new bookings using input functions and then inserts the data as a new entry in the bookings table. Note that dots (.data.You can use blank lines and indentation to indicate the structure of the script. This allows you to insert comments in a script. This is especially useful if the variable is an important global variable or if it performs a complex function in a script. Comments The shell disregards any line in a script that begins with a hash (#). At the beginning of the read. This allows you to create similar variables ± such as package_name and read. Variable names If you name variables and functions after the tasks they perform. It's also a good idea to insert a comment at the beginning of a script. you should insert a comment like the following: # This function reads a customer's name and contact details from user input. These techniques make it easier for you to debug the script after you've written it. it's a good idea to insert them liberally so that other users can work out what each part of your script is for. but they will be more transparent.) and underscores (_) don't split a name. When you create a variable. If. an appropriate comment for explaining a specific variable is bookingID=$2 #unique ID number for the new booking .

you should ensure that it's readable to human readers. you can indent lines by a number of spaces. the UNIX shell ignores white space in scripts. There's no such thing as a script with too much white space ± empty lines can only make a script more readable and reduce eye strain for the reader. This example of an if statement shows sensible use of indentation: if [$bool1 = n] then rmdir /shared/$tour echo "Rerun add_tour to start again. You should do this for any lines enclosed in a loop or an if statement. You can insert empty lines and spaces before lines of code without affecting the running of a script. you should use variable and function names that reflect the purposes of the corresponding variables and functions. Indentation Because the shell doesn't respond to initial spaces at the beginning of a line. or script is for.White space Except for spaces in individual command lines. You can split the main script at any point you choose ± for example when one task has been accomplished and another begins." exit else touch /shared/$tour/status$tour chmod 666 /shared/$tour/status$tour fi Summary When writing a script. You should insert explanatory comments wherever necessary so that readers know what each function. This is useful if you want to make a script more readable by separating functions. variable. Table of Contents | Top of page | | Abstract | . To help human readers understand the script. You can also make the structure of the script easier to understand by using blank lines and indentation. so that the beginning and the end of the statement are obvious to the reader. both from each other and from the main script.

All rights reserved. | Print | Contents | Close | Debugging and error-handling UNIX shell scripts Learning objective After completing this topic. You can reduce the effort of debugging by carefully examining your script at the design stage. you should be able to explain how to debug shell scripts. it's very useful to structure the script in a way that makes it easy for you to make sense of it. 4. Arithmetic substitution Function calls and arguments Program flow Variable values . The more complex a script is. 2. Question What do you think you need to keep track of when you analyze a script at the design stage? Options: 1.| Introduction | | Variable names | | Comments | | White space | | Indentation | | Summary | Copyright © 2003 SkillSoft PLC. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft PLC in the United States and certain other countries. 3. All other logos or trademarks are the property of their respective owners. Troubleshooting principles Once you've written a shell script ± unless it's a very simple one ± it's likely to contain a few bugs. the more time you'll have to spend debugging it. 1. For this reason.

you may encounter the following types of errors: y y y logical errors resource errors syntax errors logical errors Logical errors occur as a result of errors in program flow. $ user_backup cp: file: No such file or directory $ syntax errors Syntax errors occur as a result of lexical errors ( such as misspelled variable names and parentheses or quotes that haven't been closed ( in scripts. $ user_backup user_backup[3]: syntax error: 'while' unmatched $ . You also need to keep track of variables you've declared. a script may refer to a file that doesn't exist or it may need to modify a file to which it doesn't have write permissions. If it requires user input. Then you try running the script.Answer You need to analyze the logical flow of your script. or it may be passing a string to a function that performs integer arithmetic. For example. you write the script code. you should test a wide range of input values ( including completely inappropriate values ( to see how the script responds. including where they are used and what values they're likely to have. Once you've sketched the program flow for a script and have eliminated any logical problems at the design stage. Copying Copying Copying Copying file file file file file file file file @a @a @a @a to to to to backup backup backup backup directory« directory« directory« directory« resource errors Reference errors occur when scripts require resources that they can't access. For example. you need to be aware of the functions that should be called at each stage and of which arguments these functions should use. When testing a script. For example. a script may fail to terminate because it's caught in a logical loop.

Once you've established what the effects of a bug are. you need to find out why the exit conditions for the loop aren't being met. Perhaps it's because a variable value is wrongly assigned at some other point in the script. Logical errors result from design flaws. you can begin finding a way to fix the bug. If the script gets stuck in a logical loop. This may be as simple as correcting a spelling mistake. You first need to find the place in the script at which things begin to go wrong. and if a set of quotes isn't complete a syntax error will be generated. for example. you should try to reproduce the error by running the script again with similar input. However. . Question Match the examples to the corresponding error type. this indicates a fixable bug. Options: 1. The program contains an opening quote that isn't closed 2. If you can't get the error to repeat. you can begin looking for its causes. Syntax errors are generated by mistyping variable or command names. if it repeats in a predictable way. Resource error C. The program is caught in a loop that fails to finish 3. Once you've located the cause of a bug. or it may involve rewriting sections of code. such as passing improper arguments to functions or failing to terminate loops. Logical error B.If one of your test runs of a script produces an error. an attempt to write to a non-existent directory is a resource error. and not using the correct format for commands. The program tries to write to a directory that doesn't exist Targets: A. Syntax error Answer An infinite loop is an example of a logical error. you can't make any further progress towards solving the problem.

You use the echo statements to output the name and value of a variable at different stages in the script. Preparing your program in pseudocode helps to eliminate this type of error. Question Which of the following types of error can be minimized at the design stage of writing a program? Options: 1.Resource errors result from a script not being able to access external commands or filesystem locations ± either because they don't exist or because the requisite permissions aren't in place. $ echo "customerID = $customerID" customerID = 411 $ . so they aren't encountered at the design stage. Option 2 is incorrect. To do this. Option 3 is incorrect. or nonexistant filesystem resources ± are usually encountered during the writing and testing of a program. Syntax errors are only encountered once you start to write a program. Resource errors ± such as incorrect permissions. Logical errors 2. Option 1 is correct. 2. you need to track changes in variable values and the direction of program flow. Resource errors 3. The easiest and simplest way to track variables is by introducing large numbers of echo statements into a script. Tracking variables Finding the place in a script that's causing a bug is the most difficult part of debugging. Syntax errors Answer Logical errors can usually be minimised by planning your programs carefully at the design stage. Logical errors are usually the result of design flaws.

Statements that assign values to variables . Question What kind of statements do you think you need to execute in traps when you're debugging a script? Options: 1. the echo statement displays the current value of two variables. Traps are statements that execute if the script receives a particular signal. name is $name" done You can use traps to track a particular variable or set of variables. this echo statement at the beginning of a function displays the values of any arguments passed to the function. read.customer. you can disable the echo statements by commenting them out. This allows you to re-enable them if you need to debug the script again in the future. name is $name" done Detailed output from echo statements is necessary for debugging only. while $count<$total do name=new_entry[0] touch "$name _data" count+=1 # echo "iteration $count. while (($count<$total)) do name=new_entry[0] touch "$name _data" count+=1 echo "iteration $count. Once you've finished debugging a script.For example.info () { > echo $* > new_entry[0]=$1 > new_entry[1]=$2 > new_entry[2]=$3 > new_entry[3]=$4 > } $ This example shows an echo statement in a loop. Each time the loop executes.

you need to enter the trap statement at the beginning of the script. If you want a trap to remain active throughout a script. This allows you to view variable values at the point at which errors occur. $ trap showvars DEBUG A trap is active from the position of the trap statement onwards. if its exit status is non-zero. This is especially useful if you're dealing with an error that causes a script to exit prematurely because it allows you to display the values of important variables immediately before the script crashes. ERR The ERR trap causes a statement to execute whenever a statement in the script causes an error ± in other words. Statements that echo variable values 4. you use the DEBUG trap to run the showvars function after each script statement executes. DEBUG EXIT ERR . EXIT The EXIT trap causes a statement to execute when a script exits.2. you need to use the traps to run statements that echo variable values. but it doesn't allow you to trace them through the statements that lead up to that point in a script. Statements that exit the script Answer When you debug a script using traps. Statements that echo an error message 3. This allows you to display the value of a variable every time the script executes a statement. You use this syntax for trap statements. To deactivate a trap. The most relevant traps for debugging are y y y DEBUG The DEBUG trap causes a statement to execute each time a line of code in the script executes. you use another trap statement without specifying a command. trap command signal In this example.

$ trap .DEBUG In this example. Any line in a shell script that is preceded by a # is treated as a comment. including lines containing the echo command. for instance. Option 3 is correct. you use the EXIT trap to run the exitmsg function if the script receives an EXIT signal. 2. Which signal do you specify for the trap command? . but it can't be used to rename variables. This function might contain commands that display the values of all variables and the line number of the last executed statement. Option 2 is incorrect. so it is useful for monitoring variable values in order to debug programs. 3. $ trap exitmsg EXIT Question Identify the true statements about the echo command. 4. Option 4 is correct. You can include echo commands in your code without affecting control flow You can use the echo command to rename variables You use the echo command to print a variable without modifying its value You use the # symbol to turn echo commands into comments Answer The echo command does not modify the values of variables and doesn't affect control flow within scripts. so is useful for debugging programs. Options: 1. Question You have written a shell program that creates several temporary files. You use the # symbol to turn echo commands into comments. The echo command simply prints any arguments to standard output. The echo command can't modify the value of variables passed to it in arguments. You want to use the trap command to remove these files if the program exits unexpectedly. Option 1 is correct. The echo command will print the value of any variable passed to it as an argument. It doesn't affect control flow.

. arithmetic. Option 3 is correct. The EXIT command is used to create a trap that executes code ± in this case code that removes temporary files ± when a program terminates. 3. and it echoes each stage of variable. or command substitution. The DEBUG signal is used to create a trap that executes code after every command in the scripts is executed. you can set debugging options when you run it. EXIT Answer You use the EXIT signal if you need to execute code when a program exits. The specified code will be executed even if the program terminates unexpectedly. Option 1 is incorrect. ERR 3. The ERR signal is used to create a trap that executes code after every error command. xtrace The xtrace option echoes each statement in a script as it's executed. verbose The verbose option echoes all input that a script receives to the standard error file. Advanced debugging techniques To assist in debugging a script. This is useful when you want to check for syntax errors or when you suspect that a bug may hang the system. DEBUG 2. This is a powerful way of detecting bugs that occur in the substitution stages of a statement. The following shell options are useful for debugging: y y y noexec verbose xtrace noexec The noexec option causes the shell to read a script without executing any commands. whether or not the error causes the program to exit.Options: 1. Option 2 is incorrect. This can help you to locate a bug by allowing you to identify which input the script received immediately before an error occurred.

$ set +o verbose Note You can't unset the noexec option because it prevents the set +o command from executing. The xtrace prompt ± in this case a plus sign (+) ± indicates how many levels of substitution are occurring for a particular line. You do this by using the first letter of the debugging option. xtrace Answer . You set debugging options using the set command with the -o option. for example. verbose 3. The code shown here unsets the verbose option. $ set -x To unset a debugging option.This example of xtrace output shows how stages of execution are displayed. you use the set +o command. Question Which debugging option do you think allows you to view the input that a script receives? Options: 1. The code shown here sets the verbose option. This code. sets the xtrace option. $ set -o verbose You can run the set command without the -o option. $ ((res = 36/4 + $i)) + let res = 36/4 + 3 $ Note You can customize the xtrace prompt using the PS4 environment variable. The example shows one level of variable substitution in which the number 3 is substituted for the variable i. noexec 2.

To run the Bash debugger on a script. Option 2 is incorrect. the Bash shell provides the Bash debugger. . The xtrace option displays each command as it is executed and is the most appropriate option for general debugging. you run a session of the Bash shell and specify the -debugger option. Option 1 is incorrect. $ bash --debugger add_pkg_files Question Which debugging option allows you to monitor substitution as commands in a script execute? Options: 1. verbose 3. A debugging script appends itself to the target script and enables various debugging tools. xtrace Answer The xtrace option allows you to monitor substitution as commands in a script execute. The noexec option reads commands without executing them. The verbose option causes input to be displayed as it is read. For example. It's useful for discovering syntax errors. A debugging script allows you to y y y y start a script with debugging options cause a script to exit under specified conditions display data if a script crashes change a script so that you can test debugging solutions You can write your own debugging script. Option 3 is correct. noexec 2.The verbose debugging option allows you to view the input that a script receives. The most powerful tool for debugging a script is a debugging script. but some shells provide an existing debugger. It's useful for verifying input.

Option 4 is correct. When you execute a debugging script you supply the target script as a parameter. Options: 1. Handling user errors If you're developing a script that requires input from users. you need to include statements that check the input to make sure it makes sense. 4. Exit the script 2. 2. Option 2 is incorrect. an input function that reads a time shouldn't accept hours lower than zero or higher than 24. Question What do you think error-handling code needs to do if a user enters inappropriate input? Options: 1. Option 3 is correct. A debugging script appends itself to the target script You can use a debugging script to automatically correct logical errors You can use a debugging script to display data when a script exits unexpectedly You can use a debugging script to enable debugging options Answer A debugging script appends itself to the target script. The debugging code is appended to the code of the target script. For example. You can use a debugging script to set shell options ± such as the xtrace option ± that facilitate debugging. Print an error message . but it won't correct it. Option 1 is correct. 4. A debugging script may help you locate the source of a logical error. A debugging script can be used to set traps that print useful data ± such as the values of variables ± when a program exits unexpectedly. You can use it to enable debugging options and display data when a script exits unexpectedly.Question Identify the true statements about debugging scripts. 3.

which incorporate various debugging tools. Print variable values 4. These allow you to investigate how the script runs. This example shows part of a function that reads a date from user input.3. read. they frequently contain bugs. When you write scripts that accept user input. you should include statements that test the input to make sure it makes sense. You can avoid some bugs by checking program logic thoroughly before you write a script. You can also use traps to display variable values when certain conditions occur. You can set debugging options when you run a script. the error-handling code in the script should provide a simple error message and exit the script. You can also use debugging scripts. You can locate bugs by inserting echo statements that allow you to trace the values of variables at different points in the script's execution. but you need to remove other bugs after writing. To do this. you need to find the place in the script that causes the bug and then formulate a solution that fixes it. Restart the script Answer If user input doesn't fit into the range of input that makes sense. Troubleshooting principles | .date () { > echo "Enter month:" > read month > if ((month<0)) | ((month>12)) > echo "Invalid month!" > exit > fi Summary When you write complex shell scripts. It checks the input to ensure that it makes sense and displays an error message and exits if it doesn't fit into the required range of values. Table of Contents | Top of page | | Learning objective | | 1.

Scenario You've written a script that creates a shared directory. Tracking variables | | 3. All rights reserved. It allows a user to specify the directory's name and to undo the creation process if they've made a mistake. you can proceed to the next topic. | Print | Contents | Exercise: Debugging a UNIX shell program A note about exercises This exercise is designed for practice use and does not contain new learning content. If your computer doesn't have an application or applications required to carry out the exercise tasks. All other logos or trademarks are the property of their respective owners. Advanced debugging techniques | | 4. Handling user errors | | Summary | Copyright © 2003 SkillSoft. Task list Number Instructions 1 Remove the bugs from the following script: #!/usr/local/bin/ksh DirPath="/home/shared/" Exist=0 while [[ $Exist -ne 0 ]] do . In its current state.| 2. or if you would prefer to perform the exercise at another time. you've run the script and discovered that it has bugs. However. Exercise Your assignment for this exercise is to find and eliminate all bugs in the script. the script contains two logical errors and three syntax errors. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries.

. $USER Please type the Directory Then press Enter:" read DirName if [[ -d $DirPath]]. Please Enter Another Directory" else Exist=0 fi done clear mkdir -m 777 $DirPath$DirName echo "The $DirName directory has been created in $DirPath. Table of Contents | Top of page | | Scenario | | Exercise | Copyright © 2009 SkillSoft. All other logos or trademarks are the property of their respective owners. when you are satisfied with it. Are you happy with this?" read -p "[y/n]" BOOL1 clear if [ $BOOL1 = n ] then rmdir $DirPathDirName echo "$DirName has been removed" exit else touch $DirPath$DirName/status$DirName chmod 666 $DirPath$DirName/status$DirName if Review your solution and. open the solution page. SkillSoft and the SkillSoft logo are trademarks or registered trademarks of SkillSoft in the United States and certain other countries. All rights reserved. then Exist=1 echo "*************************************************** DIRECTORY EXISTS.Task list Number Instructions echo "*************************************************** Welcome.

Sign up to vote on this title
UsefulNot useful