sections in this module | City College of San Francisco - CS160B Unix/Linux Shell Scripting Module: Shell Basics |
module list |
This section contains examples of Shell Basics. Most of the answers are at the end of the section, with some comments. Some of them require you to actually test the solutions on your own. These examples are not meant to replace the Exercises. Do the exercise sets!
Some of the exercises have sample
files. The sample files are on hills in a subdirectory beneath
/pub/cs/gboyd/cs160b/examples-shotts. The sample files for this set of
examples would be in the subdirectory named basics.
1. Given two integers xxx and yyy, write a command to
4run | num.ber | num_ber | _4run | comma,s |
typ4me | typO | verylongvariablename | ALLCAPS | techno-crat |
3. Alexi found the following line in the beginning of a shell script:
TESTDIR=${TESTDIR:-$PWD}
Explain to him what it means.
4. What does the following command sequence do?
5. Li wants his prompt to double as a clock. He sets his prompt like this:
However, when he types enter, the date in the prompt doesn't change. What is the problem and how can he fix it?
6. You have two files, file1 and file2. Write a command to output how many more lines file1 has than file27. It was a messy breakup and Susan is writing a 'dear John' letter in a shell script. (ok, you have to smile at that one.) She figures he owes her some money, so she's adding that into her message. If the amount owed is in a variable $owed, write an echo statement that will output the following text exactly:
I say, "It's over! and you owe me $XXX"
where XXX is the value of $owed
8. Write a shell script mystat that outputs the following information:
formatted as follows:
You may want to look at the output of the following commands to extract your data:
Solutions
1a. There are several ways to do this:
2. 4run num.ber comma,s and techo-crat are illegal. A variable name may include letters, numbers and underscores, but it cannot start with a number.
3. The shell script is ensuring that the variable TESTDIR has a value. If it was set and exported, the shell script will use the value. If it was not set (or not exported), the shell script will set TESTDIR to the current directory. Note that, in this case the syntax TESTDIR=${TESTDIR:=$PWD} is no different.
4. It outputs how many lines in $file contain at least one instance of Henry.
5. The problem is when the date command is run. When $(date) is in double-quotes, it is run and the result assigned to PS1. This is what you normally want when you are using command-substitution. This results in a constant date being assigned to PS1. In the case of prompt strings, however, they are re-evaluated each time the prompt is output. Thus, if PS1 has the string $(date) in it when the prompt is printed, the date command is rerun each time the prompt is printed, which is what you want. You can see this in the following two examples. The first evaluates the date when PS1 is assigned. The second evaluates it whenever the prompt is output.
$ PS1="$(date) "; set | grep "^PS1"
PS1='Sat Apr 3 14:40:39 PDT 2010 '
Sat Apr 3 14:42:41 PDT 2010 # these are instances of the new [ugly] prompt
Sat Apr 3 14:42:41 PDT 2010
$ PS1='$(date) '; set | grep "^PS1"
PS1='$(date) '
Sat Apr 3 14:42:13 PDT 2010 # these are instances of the new [ugly] prompt
Sat Apr 3 14:42:15 PDT 2010
You could alternately escape the $ in the command-substitution when you assign to PS1:
PS1="\$(date): "
6. echo "$(( $(wc -l < file1) - $(wc -l < file2) ))"
(This is command-substitution embedded inside arithmetic substitution. The extra spaces between the $(( and the $( are not required, but are there for clarity. Of course, if file2 has more lines than file1, the result will be a negative number.)
7. This is all about using quotes correctly, and is difficult as you have a mixture of single- and double- quotes in the output. Here are some suggestions:
echo "I say, \"It's over! And you owe me \$$owed.\""
echo 'I say, "It'\''s over! And you owe me '$owed.'"'
echo I say, \"It\'s over! And you owe me \$$owed.\"
Although it is not apparent here, the real problem in this sequence can be the exclamation point(!). If an exclamation point is a prefix to any text, it is interpreted as a history substitution. The only way to disable this is to use single-quotes. In our example, we are safe, since the exclamation point was followed by a space.
8. The resulting shell script mystat is in this module's directory beneath examples-shotts/basics on our public work area on hills. A copy is below:
$ pwd
/pub/cs/gboyd/cs160b/examples/3-basics2
$ cat mystat
#!/bin/bash
#
# this shell script outputs the following information
# - the host it is being run on, and the date and time run.
# - how long the system has been up
# - how many users there currently are
#
h=$(hostname)
#
# break apart the date using set --
# the date command outputs this syntax:
# Sat Apr 3 15:15:29 PDT 2010
#
set -- $(date)
date="$2 $3 $6"
time=$(echo "$4" | cut -d: -f1-2)
#
# the uptime command outputs this format:
# 3:17pm up 94 days, 21:37, 6 users, load average: 0.05, 0.06, 0.06
# we will just output the days up, and we'll use sed to capture it
# the following command captures the longest sequence of text that does not
# contain a comma after the string 'up ', then just substitutes what it
# captured for the entire line.
#
up=$(uptime | sed 's/.*up \([^,]*\).*/\1/')
#
nusers=$(who | wc -l)
#
# now we're ready to output the results:
echo "Welcome to $h. It is $date at $time."
echo "The system has been up for $up. There are $nusers users."
Prev | This page was made entirely with free software on Linux: Kompozer and LibreOffice.org |
Next |