Answers to Selected Problems

Answers to Selected Problems

Answers to selected problems Chapter 4 1 Whenever you need to find out information about a command, you should use man. With option -k followed by a keyword, man will display commands related to that keyword. In this case, a suitable keyword would be login, and the dialogue would look like: $ man -k login ... logname (1) - print user’s login name ... The correct answer is therefore logname.Tryit: $ logname chris 3 As in problem 4.1, you should use man to find out more information on date. In this case, however, you need specific information on date, so the command you use is $ man date The manual page for date is likely to be big, but this is not a problem. Remember that the manual page is divided into sections. First of all, notice that under section SYNOPSIS the possible format for arguments to date is given: NOTE SYNOPSIS date [-u] [+format] The POSIX standard specifies only two This indicates that date may have up to two arguments, both of arguments to date – which are optional (to show this, they are enclosed in square some systems may in brackets). The second one is preceded by a + symbol, and if you addition allow others read further down, in the DESCRIPTION section it describes what format can contain. This is a string (so enclose it in quotes) which 278 Answers to selected problems includes field descriptors to specify exactly what the output of date should look like. The field descriptors which are relevant are: %r (12-hour clock time), %A (weekday name), %d (day of week), %B (month name) and %Y (year). The argument you would give to date would therefore be: +"%r on %A %d %B %Y" so that the command you would type would be date +"%r on %A %d %B %Y" 5 The first decision to be made is which command to use to display the machine’s users. Use man with a suitable keyword: $ man -k logged ... who (1) - show who is logged on ... The script should therefore echo the one-line message and then run who: echo "The following are logged in:" who Chapter 5 By this stage, you should be getting used to using man to decide which commands to use, and to decide which options to give to commands. NOTE 1 Use ls with options -a (to include listing ‘dot’ files), -1 (to list ‘1’ is digit one filename on each line of output) and -t (to list in order of modification time). Pipe this output to head, with option -n 3 (to select the first three lines in the list): ls -1at | head -n 3 3 Use ls with option -i (to list inodes as well as filenames), and pipe the output to sort with option -n (to indicate numerical rather than lexical order): NOTE $ ls -i | sort -n 5 Running ls with options -l and -d followed by a dot (the current ‘l’ is lower-case letter l directory) will display details about the current directory. The owner of the file begins in character column 16 and may continue until column 23, so use cut with option -c to select columns 16 to 23: 279 Introducing UNIX and Linux ls -ld . | cut -c 16-23 7 Use ls with option -l, and pipe the output to sort. Since the fifth field is the field which is to be used for sorting comparisons, argument +4 should be given to sort (thefieldsarecounted starting from 0). The sort should be according to numerical order rather than lexical, so sort requires option -n also: ls -l | sort -n +4 Chapter 6 1 Use crontab -e to edit the crontab file, adding the following line to that file: 0 8 * * 1 echo "Good Morning" This instructs crontab to run echo "Good Morning" (whose output will be mailed to you) at 0 minutes past 8 o’clock every first day (i.e. Monday) of every week regardless of the month or the date. 3 Use at to schedule the alarm call by giving it argument now + 1 hour. Remember that at will mail you the standard output from the commands you give it, so you must send the message directly to the device which is your terminal. You can find out the device name using tty: $ tty /dev/ttypf $ at now + 1 hour at> echo "Your alarm" >/dev/ttypf at> ctrl-D 5 This is an exercise in knowing the names of the environment variables which store the relevant information. These were presented in Table 6.1. echo "Your username is $LOGNAME" echo "Home directory is $HOME" echo "You are using a terminal which is a $TERM" echo "The default lineprinter is $PRINTER" 7 Set MY NAME to be the string containing your first and family names, and enclose that string in quotes so that the blank space betweenthetwonamesispartofthatstring: $ MY NAME="Chris Cringle" 280 Answers to selected problems Chapter 7 1 Use find followed by a tilde (the current directory) to select files from the current directory, and argument -print to list them. Other arguments are needed to perform the selection, and as there are many possible arguments you should read the manual page. Argument -type f selects regular files. To check on the file size, argument -size followed by an integer n selects all files whose size is between (n − 1) and n blocks of 512 bytes. The command becomes: $ find ~ -type f -size 1 -print 3 The script must initially check that all the arguments are readable; then it can simply pass them all to cat: for i in "$@" # For each argument do if [ ! -r "$i" ] # if it is not (!) readable (-r) then exit 1 # then bomb out fi done cat "$@" # cat the files 5 Use printf to format and who to find the users. With option -q two lines will be displayed by who, the first contains the users, the second the number of them. Use head to select the first line of the output of who -q,thenafor loop to print out each of them in turn. A count must also be made so as to know when to finish a line of output. COUNT="" # Use to count to 4 ALLUSERS=$(who -q | head -1) # Get the list of users for i in $ALLUSERS # Loop through in turn do printf "%10s" $i # Print each in width 10 COUNT=$COUNT"x" # Add an "x" to COUNT if [ "$COUNT" = "xxxx" ] # If 4 "x"s in COUNT then printf "\n" # terminate the line COUNT="" # and reset COUNT fi done # At the end, if the final line contains less than # four columns, that line must be terminated if [ "$COUNT" != "" ] then printf "\n" fi 281 Introducing UNIX and Linux 7 You need to keep a count of the number of the line, which can be incremented with the aid of bc.Useread to read in the standard input line-by-line, and printf to ensure that the format is the same as cat -n (i.e. six character columns for the line number, followed by two blank spaces, followed by the line). LINENUMBER=1 # To store the line number while read LINE # ‘read’ returns false at end do # of input # Print the line number and the line printf "%6d %s\n" $LINENUMBER $LINE # Add one to the line number LINENUMBER=$( echo "$LINENUMBER + 1" | bc ) done Chapter 8 1 This is an exercise in arithmetic expansion only. printf "Enter cm: " # Prompt read CM # Read number of cm FEET=$(( $CM / 30 )) # FEET is easy to calculate CM=$(( $CM % 30 )) # Replace CM by residual cm # above the previous feet INCHES=$(( $CM * 12 / 30 )) # Convert residual cm # to inches printf "%d cm is %d foot %d inches\n" $CM $FEET $INCHES 3 This exercise requires the use of the test command at the start to perform the checks on the filename given as argument to the script, followed by a miscellany of UNIX utilities. # Check number of arguments if [ $# -ne 1 ] then echo "Requires one argument" exit 1 # If a single argument, check it’s readable elif [ ! -r $1 ] then echo "File is unreadable" exit 1 fi LINES=0 # To count number of lines COL=0 # To count number of characters while read LINE # read returns false at end of input do 282 Answers to selected problems # Characters on line (including Newline) COLONLINE=$( echo "$LINE" | wc -c ) # Add to COL and subtract 1 for the Newline COL=$(( $COL + $COLONLINE - 1 ) # Increment line count LINES=$(( $LINES + 1 ) done <$1 # Input from the file # Since 2 decimal places needed, must use bc to # calculate the average, not arithmetic expansion AVERAGE=$( echo "scale=2; $COL / $LINES" | bc ) # Finally, display the average printf "Average is %s\n" $AVERAGE 5 Use date to display the hour, then pattern match on the output: # Format %H gives the hour as 2 digits, 00-23 case $( date "+%H" ) in # Any hour 00 to 09, also 10 or 11 0?|1[01]) echo Good Morning ;; # Any hour 12 to 17 1[2-7]) echo Good afternoon ;; # Any other time is evening *) echo Good evening ;; esac 7 This solution involves a moderately complex while loop. # Check number of arguments if [ $# -ne 1 ] then echo "Requires 1 argument" exit 1 fi # Check the argument is between 1 and 15 case $1 in [1-9]|1[0-5]) ;; *) echo "Require number 1-15" exit 1 esac LINE=1 # Use to count through the lines while [ $LINE -le $1 ] 283 Introducing UNIX and Linux do # For the top and bottom lines of the square if [ $LINE -eq 1 ] || [ $LINE -eq $1 ] then printf "+" # First column COL=2 # Column to print in next while [ $COL -lt $1 ] do printf "-" COL=$(( $COL + 1 ) done printf "+\n" # Last column, and end line # The middle lines else printf "|" # First column COL=2 # Column to print in next while [ $COL -lt $1 ] do printf " " COL=$(( $COL + 1 ) done printf "|\n" # Last column, and end line fi LINE=$(( $LINE + 1 ) done 9 This could be solved using pattern matching on the arguments, but since there are many possibilities for running eurhello with options, the clean way to solve the problem is with getopts.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    29 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us