CS/CE 218 Lecture -*-Outline-*- connection: We've seen how to do several things with the built-in commands of Unix, manipulating text, relations, etc. But these efforts are of limited help if we can't abstract our work by allowing parameters, by giving logical pieces names. That is we're going to write programs. * basics of the Bourne Shell advert: The Bourne shell (shell from now on) is an interpreted programming language; one whose library of built-in procedures (commands) is large and can be changed while you use it! Instead of programming at the level of integers and characters, you work at a very high level: programming-in-the-large with files and Unix commands. can invoke commands by name, like sed, grep, ... Q: What's the relationship between the shell and commands like sed? shell is a program, so is sed, grep, ... to run sed, the shell forks a child process (a copy of itself) and then execs the process to be run (replacing itself) these commands are *not* part of the shell's program you can have your own version of sed, etc. to return to the question of how to write programs... ** Shell scripts (section 13.2) You can put several lines of text in a file, the file then stands for all the commands (is an abstraction) Q: Which version of the "makelist" command on page 453 do you prefer? ------------------ # simplified version of program to print the output of tex (dviprint) dvialw -q $1 # $1 is value of first command line argument lpr -Plw1 \#${1}-alw # ditto for ${1} ------------------ tie the following in with directory permissions, links ---------------- # simplified version of program to break links to files (my) # temp file TMP=/usr/tmp/my.$$ # $$ is the process id of this script's shell for f # each command-line argument is assigned to f do cp $f $TMP rm -f $f mv $TMP $f done ---------------- *** executing shell scripts Q: What are 2 ways to execute a shell script as a "subroutine"? sh my file1 better: sh $HOME/bin/my file1 or /bin/sh $HOME/bin/my file1 or /bin/sh ./my file1 (from $HOME/bin) this starts the shell (sh) running (by using exec), which reads the file "my" as input chmod +rx $HOME/bin/my my file1 to do this, you have to have $HOME/bin in your PATH PATH=:$HOME/bin:$PATH export PATH can also say $HOME/bin/my file1 this tries to exec "my", which fails, then runs the shell with input my, as before. Q: For MS-DOS users: if in Unix you execute cmd1 below, what is the output (assume cmd2 is in a file called cmd2...)? --------------- # cmd1 echo 'start of cmd1' cmd2 echo 'end of cmd2' --------------- --------------- # cmd2 echo 'in cmd2' --------------- Note: unlike MS-DOS, these subroutines always return to their caller. (unless invoked with "exec cmd" ...) exec is useful for abbreviations (saves resources) exec lp -Plp2 $* Q: Can you explain the following. Suppose in the file cd-print is: ------------ cd $1 pwd ------------ it's executable, etc. Consider the following session ------------- $ pwd /home/cs218/cs218a00 $ cd-print $PUB /home/cs218/public $ pwd /home/cs218/cs218a00 ------------- what's going on? Shell scripts are really subroutines executed by a subsidiary shell (unless invoked with .) e.g., $ . cd-print $PUB /home/cs218/public $ pwd /home/cs218/public sourceing a script (with .) is like invoking a macro... *** shell variables (section 13.3) the things following the dollar signs are names of variables. syntax is any sequences of letters, digits, or underscores case is significant Q: what is the syntax for setting a variable? var=value Q: do variables have to be declared? what is the type of a shell variable then? a string Q: what is the syntax for getting the value of a shell variable? $var Q: what is the output of ``echo $PUB''? of ``echo $HOME''? Q: what is the value of your PATH variable? **** shell environment (predefined variables) (page 459) each shell has an environment (like a directory) maps variable names to their values Q: what variables are predefined by the shell? The initial environment: HOME - used by cd (which is part of the shell) PATH - used to find commands PS1 - prompt ***** exported vs. non-exported variables (draw box diagrams) all environment printed (to stdout) by "set" part of a shell's environment is passed to commands it invokes these are exported variables (type export or printenv) to see them. can use diff or comm to show part not exported only ***** linkage (PATH) most important exported variable is PATH... Q: how are commands found by the shell? commands are found by using the search path in the PATH var. have : at front to search current directory (important for C prog.) or use . somewhere, or an empty part... **** arguments (section 13.4) Q: How do you get the value of a command line argument in a script? $1, $2, ... $9 (this is argv in C) for more arguments, use shift, or $* or a for loop Q: What is the value of $2 if there is only 1 argument? Q: How do you get the number of the arguments to a command? $# $0 is the name by which a script was called ------------- USAGE="Usage: $0 file ..." ------------- ** substitutions shell programs deal with strings need ways of constructing these strings from other information. *** command substitution (`cmd`) page 460 extremely useful as a way to generate arguments takes the output of a command and allows you to use it in the shell (as an argument, or to set a variable) --------------------- echo 'A message from the CS/CE 218 staff (last changed' \ `ls -l $PUB/motd | cut -c42-53`'):' printascii `unit-files $d` --------------------- common to set shell variables using this ------------- OS=`$HOME/bin/ostype` user=`expr "$HOME" : '.*/\([^/][^/]*\)'` ------------- Blanks, tabs and newlines are changed to a single space ------------ $ echo 'what happens to the blanks?' what happens to the blanks? $ echo `echo 'what happens to the blanks?'` what happens to the blanks? $ echo `cat` and the newlines? ^D and the newlines? ------------ *** quotation (", ', and \) a kind of "anti-substitution" prevents a kind of substitution. device prevents example " file name expansion echo "*" " blank (arg) interpretation echo "`ls`" ' all substitution/interp. echo '$PATH\"`ls`' \ interpretation of any special echo \'\`\"\$X notes: \ is not recogized within single quotes! need \ to get a single quote to a command use " around arguments in shell scripts if need file name expansion In the Bourne shell (but not the cshell) quotations hide newlines Q: what does the following do echo 'hi there' in the Bourne shell?