-------------------------------- DAT2330 - Unix - Prof. Ian Allen -------------------------------- Here are questions you should be able to answer. You will likely find questions similar to these on tests and exams. Chapter 10 - The Bourne Again Shell (excerpts) Note: For much of the material, the Korn Shell, Bourne Shell, and Bash Shell behave identically. Note: Type in all the scripts and command lines! You can't practice debugging the scripts simply by reading them. Note: Concentrate on the text sections related to material covered in lectures, assignments, and in these questions. Skip over all the "Optional" sections in this chapter. Also skip over these sections: - "Directory Stack Manipulation" p.313 - "Removing Variables" p.322 - "The readonly builtin" p.322 - "The declare builtin" p.324-325 - the table "Special Characters / Display in Prompt" p.331 - "PS2" p.331 - "CDPATH" p.332 - "The shift builtin" p.334 - "The set builtin" p.335-337 - "History" and "Alias" p.340-350 - "Brace Expansion" p.351 - "Arithmetic Expansion" p.354 - "Word Splitting" p.356 - "Command Line Editing" p.359-362 Skip over the above sections. - Which successful shell has been used in all versions of Unix and Linux? - What is a shell script? - True or False: Shell scripts cannot have their input or output redirected; only Unix command output can be redirected. - What minimal permissions are needed on the file for a shell to read a file containing a shell script, i.e.: $ sh script - What minimal permissions are needed for Unix to execute a file containing a shell script, i.e.: $ ./script Will the shell execute a script that has execute permissions but not read permissions? (Try it!) - What is the difference between: chmod +x file chmod u+x file - p.303 - Do not expect the current directory to be in your search PATH. The system administrator has ill-advisedly included it in PATHs set for students on ACADAIX. It is *not* included under most modern versions of Unix/Linux. Read p.304 on how to execute correctly a shell script that is in the current directory. Read the top of p.330 for an explanation of the security risk of having the current directory in your search PATH. Warning: I often create test questions that create scripts that have the same names as existing (but often obscure) Unix commands! If you fail to follow the syntax given at the top of p.304 you will not be able to run your shell script. Note: The book makes two errors throughout this chapter: 1) The book fails to use "#!/bin/sh -u" to start scripts 2) The book fails to use ./scriptname to run scripts In this course (and in the real world), you must not make these two mistakes. Go through your book now and fix all the script examples! - What does the semicolon special character mean to the shell? - How would you generate the following output sentence using "echo": I read Chapter 2; so, it's easy to escape special characters. - True or False: If the command to the left of a semicolon fails (with a bad return status, or "not found"), the shell will not execute the command to the right of the semicolon. (Hint: Try it.) - Note how an ampersand ("&") puts an entire pipeline into the background: $ sort /etc/passwd | tail -15 | grep '^zoo' & - True or False: When printing to the terminal, output on standard error looks different than output to standard output. - True or False: These two command lines generate the same output: $ ls >out 2>&1 nosuchfile $ ls 2>&1 >out nosuchfile (Hint: Try them. Read p.309) - True or False: The syntax for redirecting the output of an echo command to appear on standard error (instead of on standard output) is: echo 1>&2 "This is an error on standard error" - True or False: The following three commands are identical: 1>&2 echo "This is an error on standard error" echo 1>&2 "This is an error on standard error" echo "This is an error on standard error" 1>&2 - Rewrite the last sentence on p.310 to say: The jobs builtin lists all the background jobs of the current shell. - True or False: The "jobs" command shows all background jobs, including background jobs running in other shells. - True or False: Background jobs can read from your terminal. - What is the name and process number of the "root" process on Unix? - The option "-f" gives you the nicest output from the "ps" command, especially on ACADAIX. Try both "-l" and "-f". - True or False: A process can have more than one parent process (PPID). - True or False: A process can have more than one child process. - What is your shell doing after it has found a command and started it running for you as a child process (in the foreground)? - The "cd" command is a built-in command to the shell; the shell does not look for it in your PATH, nor does the shell fork and start a separate child process to execute it. Why not? - Are all the shell variables you set and change in your shell automatically exported to all of your child processes and shells? - True or False: The Unix shells will read commands from a (single) file given as a command line argument. If there is no file argument, the shells read from standard input (as do most Unix commands). - Erase the sentence at the top of page 317 that talks about scripts running "more slowly". They do not. "bash script" and "./script" are equally good; one requires only read permission, the other requires both read and execute permission. - p.317 - In this course (and in the real world), you *must* put the name of the script interpreter as the first line. If you don't do this, the system may later choose the wrong shell to run your script. Always start Bourne-type shell scripts with: #!/bin/sh -u (The -u checks for undefined variables. Use it!) The shell /bin/sh is available on every Unix system on the planet. Only Linux systems have /bin/bash installed "out of the box". For maximum portability, use "/bin/sh" for your shell scripts. Note: The book makes two errors thought this chapter: 1) The book fails to use "#!/bin/sh -u" to start scripts 2) The book fails to use ./scriptname to run scripts In this course (and in the real world), you must not make these two mistakes. Go through your book now and fix all the script examples! - If the first line of an executable file is "#!/bin/cat", what will the output be when you execute the file? (Hint: Try it! Copy /etc/motd into a file, add "#!/bin/cat" as the first line, make the file executable, and then execute it. What do you see?) - If the first line of an executable file is "#!/bin/sort", what will the output be when you execute the file? (Hint: Try it!) - If the first line of an executable file is "#!/usr/bin/head -2", what will the output be when you execute the file? (Hint: Try it!) - If the first line of an executable file is "#!/usr/bin/tail -2", what will the output be when you execute the file? (Hint: Try it!) - If the first line of an executable file is "#!bin/nosuch", what will the output be when you execute the file? (Hint: Try it!) Remember this error message! You may see it again. - Put temporary echo commands into your .bashrc and your .bash_profile. Log out and log back in. Which echo commands executed? Now start another bash shell (from the command line). Which echo commands executed? - p.318 The last script line at the bottom of the page is missing a blank before the "-f" test. It should read: if [ -f ~/.bashrc ]; then source ~/.bashrc; fi The "if" statement is explained in Chapter 11. - What conventions do Unix programmers use when using UPPER and lower case letters in variable names? - What is a "positional parameter"? Is it the same as "a command line argument"? - Is the variable "$#" a valid name? - True or False: When assigning to a variable, you must both precede and follow the equals sign ("=") with at least one space. - True or False: putting a variable inside double quotes prevents the variable from being expanded by the shell. - True or False: putting a variable inside single quotes prevents the variable from being expanded by the shell. - What command is most often used to display the values of variables? (The text uses this command a lot!) - Fix the syntax of the following variable assignment: $ myvar=You owe me $2 CDN $ echo "$myvar" - How would you append the string " dog" to the (unknown) contents of an existing variable named "foo"? For example: $ foo=my $ [your appending shell command goes here] $ echo "$foo" my dog - Why is it critical to put double quotes around variables when you use them? (Study the glob expansions on top of p.322 and p.326!) It is essential that you quote all your variables when you use them in shell scripts. Many scripts malfunction because novice shell programmers do not do this. I will always test your scripts with shell glob special characters as input, to see if you have remembered to quote all your variables. - When would you "export" a shell variable? - Can a child process change the value of a variable in its parent process? - Note that if you use the "-u" option to the shell to catch undefined variables, you won't be able to run the "subtest" script on p.323 as written (because "subtest" uses the value of an undefined variable, which usually indicates an error in your script). - Is the "read" command run by the shell as a built-in command, or is it run in a separate process? Why? - True or False: the "read" command reads lines until you type your EOF character (usually ^D - CONTROL-D). - Experiment with Command Substitution. You can put any Unix shell command line or pipeline into a Command Substitution, and the output will be placed into the current command line by the shell, for use by some other command: $ echo "There are $(who | wc -l) users online" $ echo "There are $(ls | wc -l) non-hidden names in this directory" $ echo "The file /etc/motd contains $(wc -l " $ PS1="$PWD >" $ PS1=`$PWD >` $ PS1='$PWD >' Test your answer by using "cd" to change directories. Does your prompt change, too? - The "." (dot) or "source" command instructs the current shell to open the given file (you need read permission) and to read commands from that file and execute them directly. This differs from running a script in a subshell or separate process; because, it is the current shell that is executing the commands and all variable assignments will change variables in the current shell. - True or False: If I put the single command "exit" into an executable shell script named "myexit" and run it ("./myexit"), my current shell will exit (and I may be logged out). - True or False: If I put the single command "exit" into a readable file "myexit" and source it (". myexit" or "source myexit"), my current shell will exit (and I may be logged out). - True or False: The shell looks up the first file name argument to the "." (dot) or "source" command in my search PATH. - True or False: The first file name argument to the "." (dot) or "source" command must have execute permissions so that the shell can read it. - What is the name of the positional parameter (numeric variable name) that contains the name of the shell script being run? (p.333) - Study well the short section on "Command-line arguments" (p.333) Note! Fix the sample scripts given in the book to quote all uses of shell variables! You *must* always double-quote your variables! - True or False: The $# variable begins a comment line. - Use the argv.sh script (given above) to learn the difference between the $* and $@ variables. Write and run this small script: $ cat numargs #!/bin/sh -u # This script shows how $* and $@ are different. export PATH=/bin:/usr/bin echo "First using $*" ./argv.sh "$*" echo "Next using $@" ./argv.sh "$@" $ ./numargs a b c d $ ./numargs a\ b c\ d" $ ./numargs "a b" "c d" $ ./numargs 'a b' 'c d' - True or False: The $* variable expands to be all the files in the current directory. - True or False: The $@ variable expands to be your email address. - Put the current process id ($$) into your PS1 prompt and export it. Now start up a sub-shell (another copy of bash). The prompt should change to be the new PID of the new shell. - Predict the output of the following: $ echo $$ 1234 $ cat myscript #!/bin/sh -u # This script echoes the process ID of the shell running it. echo The PID is $$ $ ./myscript The PID is 2345 $ . myscript The PID is [what is the output] - What is the "Exit Status" of a command? (See the textbook index.) - What shell variable contains the exit status of the most recently executed command? - Do you need to quote the variables $# and $? when using them in shell scripts? Why or why not? - What is one of the first things a shell does to a command line, to generate "tokens" or "words"? - Predict the output of these commands: $ x='$$' $ echo $x $ echo "$x" $ x="$$" $ echo $x $ echo "$x" - Note: The text is wrong about the order of expansion on p.358. Items 2 through 6 (tilde, parameter, variable, command, and arithmetic) happen *at the same time*, not one after the other. You cannot have a command substitution inside a variable or inside a parameter; it doesn't work. - What are the meanings and uses of the following shell variables: HOME MAIL PATH PS1 SHELL $0 $1, $2, $3, etc. $* $@ $# $$ $? - Chapter 10 Chapter Review questions: 1,2,3,4,5,6,10,13,16 Review question 11 is wrong. Parameter expansion happens *at the same time* as variable expansion (but before pathmame expansion).