Archive for July, 2007

case $timeofday (Photo web hosting) inyes | y | Yes |

Friday, July 27th, 2007

case $timeofday inyes | y | Yes | YES ) echo Good Morning ;; n* | N* ) echo Good Afternoon ;; * ) echo Sorry, answer not recognized ;; esacexit 0How It WorksIn this script, we used multiple strings in each entry of the case so that casetests several differentstrings for each possible statement. This makes the script both shorter and, with practice, easier to We also show how the * wildcard can be used, although this may match unintended patterns. For exam- ple, if the user enters never, this will be matched by n* and Good Afternoon will be displayed, whichisn t the intended behavior. Note also that the * wildcard expression doesn t work within quotes. Try It Out Case IIl: Executing Multiple StatementsFinally, to make the script reusable, we need to have a different exit value when the default pattern We also add a setconstruct to show this in action: #!/bin/shecho Is it morning? Please answer yes or no read timeofdaycase $timeofday inyes | y | Yes | YES ) echo Good Morning echo Up bright and early this morning ;; [nN]*) echo Good Afternoon ;; *) echo Sorry, answer not recognized echo Please answer yes or no exit 1;; esacexit 0How It WorksTo show a different way of pattern matching, we change the way in which the nocase is matched. show how multiple statements can be executed for each pattern in the casestatement. Notice careful to put the most explicit matches first and the most general match last. This is importantbecause the casewill execute the first match it finds, not the best match. If we put the *)first, it wouldalways be matched, regardless of what was input.

Try It (Apache web server for windows) Out Case I: User InputWe can write

Thursday, July 26th, 2007

Try It Out Case I: User InputWe can write a new version of our input-testing script and, using the caseconstruct, make it a littlemore selective and forgiving of unexpected input. #!/bin/shecho Is it morning? Please answer yes or no read timeofdaycase $timeofday inyes) echo Good Morning ;; no ) echo Good Afternoon ;; y ) echo Good Morning ;; n ) echo Good Afternoon ;; * ) echo Sorry, answer not recognized ;; esacexit 0How It WorksWhen the casestatement is executing, it takes the contents of timeofdayand compares it to each stringin turn. As soon as a string matches the input, the casecommand executes the code following the )andfinishes. The casecommand performs normal expansion on the strings that it s using for comparison. You cantherefore specify part of a string followed by the * wildcard. Using a single * will match all possiblestrings, so we always put one after the other matching strings to make sure the casestatement endswith some default action if no other strings are matched. This is possible because the casestatementcompares against each string in turn. It doesn t look for a best match, just the first match. The defaultcondition often turns out to be the impossible condition, so using * can help in debugging scripts. Try It Out Case II: Putting Patterns TogetherThe preceding caseconstruction is clearly more elegant than the multiple ifstatement version, but byputting the patterns together, we can make a much cleaner version: #!/bin/shecho Is it morning? Please answer yes or no read timeofdayBe careful with the caseconstruct if you are using wild cards such as * in the pattern. The problem is that the first matching pattern will be taken, even if a later patternmatches more exactly. 42Chapter

untilThe untilstatement has (My space web page) the following syntax: until conditiondostatementsdoneThis

Thursday, July 26th, 2007

untilThe untilstatement has the following syntax: until conditiondostatementsdoneThis is very similar to the while loop, but with the condition test reversed. In other words, the loop tinues until the condition becomes true, not while the condition is true. The untilstatement fits naturally when we want to keep looping until something happens. As anexample, we can set up an alarm that works when another user, whose login name we pass on the command line, logs on: #!/bin/shuntil who | grep $1 > /dev/nulldosleep 60done# now ring the bell and announce the expected user. echo -e \a echo **** $1 has just logged in **** exit 0caseThe caseconstruct is a little more complex than those we have encountered so far. Its syntax iscasevariable inpattern [ | pattern] …)statements;; pattern [ | pattern] …)statements;; … esacThis may look a little intimidating, but the caseconstruct allows us to match the contents of a variableagainst patterns in quite a sophisticated way and then allows execution of different statements, depend- ing on which pattern was matched. Notice that each pattern line is terminated with double semicolons (;;). You can put multiple statementsbetween each pattern and the next, so a double semicolon is needed to mark where one statement endsand the next pattern begins. The ability to match multiple patterns and then execute multiple related statements makes the casecon- struct a good way of dealing with user input. The best way to see how caseworks is with an example. We ll develop it over three Try It Out examples, improving the pattern matching each time.

An example of the output from this script (Make a web site)

Wednesday, July 25th, 2007

An example of the output from this script is: Enter passwordpasswordSorry, try againsecret$ Clearly, this isn t a very secure way of asking for a password, but it does serve to illustrate the whilestatement. The statements between doand donewill be continuously executed until the condition is nolonger true. In this case, we re checking that the value of trythisisn t equal to secret. The loop willcontinue until $trythisequals secret. We then continue executing the script at the statement immedi- ately following the done. Try It Out Here We Go Again,AgainBy combining the whileconstruct with arithmetic substitution, we can execute a command a fixed num- ber of times. This is less cumbersome than the forloop we saw earlier. #!/bin/shfoo=1while [ $foo -le 20 ] doecho Here we go again foo=$(($foo+1)) doneexit 0How It WorksThis script uses the [command to test the value of fooagainst the value 20and executes the loop bodyif it s smaller or equal. Inside the whileloop, the syntax (($foo+1))is used to perform arithmetic eval- uation of the expression inside the braces, so foois incremented each time around the loop. Since foocan never be the empty string, we don t need to protect it with double quotes when testing itsvalue. We do this only because it s a good habit to get into. Note that the $(( ))construct was a ksh invention that has since been included inthe X/Open specification. Older shells will use exprinstead, which we ll comeacross later in the chapter. However, this is slower and more resource-intensive; youshould use the $(( ))form of the command where available. bash supports the$(( ))form, so we will generally use that. 40Chapter

Web server info - How It WorksThis illustrates the use of the

Wednesday, July 25th, 2007

How It WorksThis illustrates the use of the $(command)syntax, which we ll review in more detail later (in the sectionon command execution). Basically, the parameter list for the forcommand is provided by the output command enclosed in the $()sequence. The shell expands f*.shto give the names of all the files matching this pattern. whileSince all shell values are considered strings by default, the forloop is good for looping through a strings, but is a little awkward to use for executing commands a fixed number of times. Look how tedious a script becomes if we want to loop through twenty values using a forloop: #!/bin/shfor foo in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20doecho here we go again doneexit 0Even with wildcard expansion, you might be in a situation where you just don t know how many timesyou ll need to loop. In that case, we can use a whileloop, which has the following syntax: whilecondition dostatementsdoneFor example, here is a rather poor password-checking program: #!/bin/shecho Enter password read trythiswhile [ $trythis != secret ]; doecho Sorry, try again read trythisdoneexit 0Remember that all expansion of variables in shell scripts is done when the script isexecuted, never when it s written. So syntax errors in variable declarations are foundonly at execution time, as we saw earlier when we were quoting empty variables.

Try It Out for Loop with Fixed StringsThe (Starting a web site) values

Tuesday, July 24th, 2007

Try It Out for Loop with Fixed StringsThe values are normally strings, so we can write#!/bin/shfor foo in bar fud 43doecho $foodoneexit 0We get the following output: barfud43How It WorksThis example creates the variable fooand assigns it a different value each time around the forloop. Since the shell considers all variables to contain strings by default, it s just as valid to use the string 43asthe string fud. Try It Out for Loop with Wildcard ExpansionAs we said earlier, it s common to use the forloop with a shell expansion for filenames. By this wemean using a wildcard for the string value and letting the shell fill out all the values at run time. We ve already seen this in our original example, first. The script used shell expansion, the * expandingto the names of all the files in the current directory. Each of these in turn is used as the variable $iinsidethe forloop. Let s quickly look at another wildcard expansion. Imagine that you want to print all the script files start- ing with the letter f in the current directory, and you know that all your scripts end in .sh. You could doit like this: #!/bin/shfor file in $(ls f*.sh); dolpr $filedoneexit 0What would happen if you changed the first line from for foo in bar fud 43to for foo in bar fud 43 ? Remember that adding the quotes tells the shellto consider everything between them as a single string. This is one way of gettingspaces to be stored in a variable. 38Chapter

An empty variable then (Web and email hosting) gives us the valid

Tuesday, July 24th, 2007

An empty variable then gives us the valid test: if [ = yes ] Our new script is #!/bin/shecho Is it morning? Please answer yes or no read timeofdayif [ $timeofday = yes ] thenecho Good morning elif [ $timeofday = no ]; thenecho Good afternoon elseecho Sorry, $timeofday not recognized. Enter yes or no exit 1fiexit 0which is safe against a user just pressing Enter in answer to the question. forWe use the forconstruct to loop through a range of values, which can be any set of strings. They couldbe simply listed in the program or, more commonly, the result of a shell expansion of filenames. The syntax is simplyforvariable invaluesdostatementsdoneIf you want the echocommand to delete the trailing new line, the most portablechoice is to use the printfcommand (see the printf section later in this chapter) rather than the echocommand. Some shells use echo e, but that s not supportedon all systems. bash allows echo -nto suppress the new line, so if you are confi- dent your script needs to work only on bash, you can use that syntax. echo -n Is it morning? Please answer yes or no: Note that we need to leave an extra space before the closing quotes so that there is agap before the user-typed response, which looks neater.

elifUnfortunately, there are several problems with this very (Web server address)

Monday, July 23rd, 2007

elifUnfortunately, there are several problems with this very simple script. It will take any answer except yesas meaning no. We can prevent this by using the elifconstruct, which allows us to add a second condi- tion to be checked when the elseportion of the ifis executed. Try It Out Doing Further Checks with an elifWe can modify our previous script so that we report an error message if the user types in anything otherthan yesor no. We do this by replacing the elsewith elifand then adding another condition. #!/bin/shecho Is it morning? Please answer yes or no read timeofdayif [ $timeofday = yes ] thenecho Good morning elif [ $timeofday = no ]; thenecho Good afternoon elseecho Sorry, $timeofday not recognized. Enter yes or no exit 1fiexit 0How It WorksThis is quite similar to the previous example, but now the elifcommand tests the variable again if thefirst ifcondition is not true. If neither of the tests is successful, an error message is printed and thescript exits with the value 1, which the caller can use in a calling program to check if the script was suc- cessful. A Problem with VariablesThis fixes the most obvious defect, but a more subtle problem is lurking. Let s try this new script, butjust press Enter (or Return on some keyboards) rather than answering the question. We ll get this errormessage: [: =: unary operator expectedWhat went wrong? The problem is in the first ifclause. When the variable timeofdaywas tested, itconsisted of a blank string. So the ifclause looks likeif [ = yes ] which isn t a valid condition. To avoid this, we must use quotes around the variable: if [ $timeofday = yes ] 36Chapter

Control StructuresThe shell has (Web server iis) a set of control

Monday, July 23rd, 2007

Control StructuresThe shell has a set of control structures, and once again they re very similar to other programming languages. ifThe ifstatement is very simple: It tests the result of a command and then conditionally executes agroup of statements: ifconditionthenstatementselsestatementsfiTry It Out Using the if CommandAcommon use for ifis to ask a question and then make a decision based on the answer: #!/bin/shecho Is it morning? Please answer yes or no read timeofdayif [ $timeofday = yes ]; thenecho Good morning elseecho Good afternoon fiexit 0This would give the following output: Is it morning? Please answer yes or noyesGood morning$ This script uses the [command to test the contents of the variable timeofday. The result is evaluated ifcommand, which then allows different lines of code to be executed. Notice that we use extra white space to indent the statements inside the if. This isjust a convenience for the human reader; the shell ignores the additional white space. In the following sections, the statements are the series of commands to performwhen, while, or until the condition is fulfilled.

Photography web hosting - File ConditionalResult-d fileTrue if the file is a

Monday, July 23rd, 2007

File ConditionalResult-d fileTrue if the file is a directory. -e fileTrue if the file exists. Note that, historically, the -e option has notbeen portable, so -f is usually used. -f fileTrue if the file is a regular file. -g fileTrue if set-group-id is set on file. -r fileTrue if the file is readable. -s fileTrue if the file has nonzero size. -u fileTrue if set-user-id is set on file. -w fileTrue if the file is writable. -x fileTrue if the file is executable. We re getting ahead of ourselves slightly, but following is an example of how we would test the state ofthe file /bin/bash, just so you can see what these look like in use: #!/bin/shif [ -f /bin/bash ] thenecho file /bin/bash exists fiif [ -d /bin/bash ] thenecho /bin/bash is a directory elseecho /bin/bash is NOT a directory fiBefore the test can be true, all the file conditional tests require that the file also exists. This list containsjust the more commonly used options to the testcommand, so for a complete list refer to the manualentry. If you re using bash, where testis built in, use the help testcommand to get more details. We ll use some of these options later in the chapter. Now that we know about conditions, we can look at the control structures that use them. You may be wondering what the set-group-id and set-user-id (also known as set-gidand set-uid) bits are. The set-uid bit gives a program the permissions of its owner, rather than its user, while the set-gid bit gives a program the permissions of itsgroup. The bits are set with chmod, using the s and g options. Remember that set-gidand set-uid flags have no effect when set on shell scripts. 34Chapter