Week 3 Notes for DAT2330 - Ian Allen Supplement to Text, outlining the material done in class and lab. Remember - knowing how to find out the answer is more important than memorizing the answer. Learn to fish! RTFM![*] ([*] Read The Fine Manual) --------------- The Unix Shells --------------- What is a shell for? To find and run programs (also called commands or utilities)! (It also does programming kinds of things; but, all that is usually to aid in the finding and running of programs.) Most (but not all) commands take what as arguments? Pathnames, either file names or directory names. How does the shell help run commands? Shells provide wildcards to generate lists of pathnames as arguments for commands. Shells provide aliases and variables to save typing the same things over and over. Shells look for commands in various places, using a list of directories stored in the $PATH environment variable. Shells provide ways of recalling and editing the last commands you enter, to save retyping them. Where are wild card characters expanded? The shell does the expansion, NOT the commands. Note how different commands treat the same set of arguments differently: $ echo * $ ls -l * $ cat * The shell does not know anything about the type of command being used when it prepares the argument list for a command. Define: whitespace, arguments, wildcard, prompt Try this use of variables and notice the different output: $ var="a b c" $ echo $var $ echo "$var" $ echo '$var' Explain why the differences. ----------- Redirection ----------- Text: Chapter 5 Redirect output that would normally appear on the screen to some other place, either into the input of another command (a pipe) or into a file. Problem: Determine the largest sequence number used in creating student accounts on ACADAIX. Iterative solutions: $ echo ../* | wc $ echo ../* | tr ' ' '\n' | wc $ echo ../* | tr ' ' '\n' | head $ echo ../* | tr ' ' '\n' | sed -e 's/^[^0-9]*/& /' | head $ echo ../* | tr ' ' '\n' | sed -e 's/^[^0-9]*/& /' | sort +1nr | head An alternative solution: $ ls .. | sed -e 's/[0-9]/ &/' | sort +1n | tail A solution that doesn't work: $ ls ../* | sed -e 's/[0-9]/ &/' | sort +1n | tail The Unix O/S has a limit on the amount of text that can be passed to a command as arguments. On ACADAIX, "../*" exceeds this limit. Do you see why "ls ../*" and "ls .." are quite different in this respect? The only reason "../*" works for the "echo" command is that "echo" is a built-in part of most shells, and most shells don't limit the amount of argument text that can be passed to built-in commands. If you retyped the line as "/bin/echo ../*", which uses the real Unix echo command, you'll find it doesn't work either: bash$ /bin/echo ../* bash: /bin/echo: Arg list too long $ /bin/echo ../* ksh: /bin/echo: 0403-027 The parameter list is too long. You will note that the error message says "too long" instead of "longer than NNN bytes". Not very helpful, is it? When you issue error messages about exceeding limits, remember to tell the user what the limits are! More wildcards: Ranges $ echo ../[a-c]* $ echo ../*[3-5] $ echo ../[r-t]*[13579] Redirection into files: $ echo hello $ echo hello >file Shells don't care where you do the redirection: $ echo hi there mom >file $ echo hi there >file mom $ echo hi >file there mom $ echo >file hi there mom $ >file echo hi there mom Like wildcarding (called "globbing" on Unix), shells handle redirection. The command doesn't see any part of the redirection syntax. $ echo hello there - shell calls echo with two arguments ==> echo(hello,there) - output appears in default location (your screen) $ echo hello there >file - shell creates "file" and diverts output into it - shell calls echo with two arguments ==> echo(hello,there) (note: NO CHANGE from previous example) - echo echoes two arguments - output is captured in "file", NOT on your screen Unix Big Mistake #1: $ cat * >z - shell creates "z" and redirects all future command output into it - shell expands wildcards; wildcard "*" includes file "z" - shell finds and calls cat command with all file names as arguments ==> cat(a,bcd,e,file1,file2,...etc...,z) - cat command processes each argument, opening the file and sending the output into file "z" - when cat opens file "z", it ends up reading and writing to the same file - Result: an infinite loop that fills up the disk drive as "z" gets bigger and bigger Fix: $ cat * >.z - uses a hidden file not matched by "*" wildcard Unix Big Mistake #2 $ cat a b >a - shell creates "a" and redirects command output into it - original contents of "a" are GONE - shell finds and calls cat command with two arguments ==> cat(a,b) - cat command processes "a" (empty file) - cat command processes "b"; output has been redirected by the shell to appear in file "a" - Result: file "a" gets a copy of "b"; original contents of "a" are lost Fix: $ cat b >>a - appends file "b" safely to the end of "a" ------- Aliases ------- Watch out for "helpful" system admin that define aliases for your shells when you log in. To avoid pre-defined aliases, start up a fresh copy of the shell. Some useful aliases: $ alias a=alias $ a lsla="ls -laF" $ a lslt="ls -latF" $ a recent="ls -latF | head" $ a veryold="ls -latF | tail" $ a findbob="who | grep abcd0001" $ a hibob="banner 'Hi bob!' | write abcd0001" What do these aliases do? --------- Variables --------- Variables, blanks, and quoting combined: $ boo='hi there' $ echo $boo $ echo "$boo" $ echo '$boo' Explain the three outputs. Variables, wildcards, and quoting combined: $ boo='*' $ echo $boo $ echo "$boo" $ echo '$boo' Explain the three outputs.