Archive for July, 2007

In shell (Web hosting providers) scripts, the dot command works a

Tuesday, July 31st, 2007

In shell scripts, the dot command works a little like the #includedirective in C or C++. Though it doesn tliterally include the script, it does execute the command in the current context, so you can use it to incor- porate variable and function definitions into a script. Try It Out The Dot CommandIn the following example, we use the dot command on the command line, but we can just as well use a script. 1.Suppose we have two files containing the environment settings for two different developmentenvironments. To set the environment for the old, classic commands, classic_set, we bin/shversion=classicPATH=/usr/local/old_bin:/usr/bin:/bin:. PS1= classic> 2.For the new commands we use latest_set: #!/bin/shversion=latestPATH=/usr/local/new_bin:/usr/bin:/bin:. PS1= latest version> We can set the environment by using these scripts in conjunction with the dot command, as in the lowing sample session: $ . ./classic_setclassic> echo $versionclassicclassic> . latest_setlatest version> echo $versionlatestlatest version> echoDespite the X/Open exhortation to use the printfcommand in modern shells, we ve been followingcommon practice by using the echocommand to output a string followed by a newline character. Acommon problem is how to suppress the newline character. Unfortunately, different versions of UNIXhave implemented different solutions. The common method in Linux is to useecho -n string to output but you ll often come acrossecho -e string to outputc

echo > fred2mkdir fred3echo > fred4for file in (Starting a web site)

Tuesday, July 31st, 2007

echo > fred2mkdir fred3echo > fred4for file in fred* doif [ -d $file ]; thenecho skipping directory $file continuefiecho file is $filedonerm -rf fred* exit 0continuecan take the enclosing loop number at which to resume as an optional parameter so that youcan partially jump out of nested loops. This parameter is rarely used, as it often makes scripts muchharder to understand. For example, for x in 1 2 3doecho before $xcontinue 1echo after $xdoneThe output will bebefore 1before 2before 3The . CommandThe dot (.) command executes the command in the current shell: . ./shell_scriptNormally, when a script executes an external command or script, a new environment (a subshell) is cre- ated, the command is executed in the new environment, and the environment is then discarded apartfrom the exit code that is returned to the parent shell. But the external source and the dot command (twomore synonyms) run the commands listed in a script in the same shell that called the script. This means that normally any changes to environment variables that the command makes are lost. Thedot command, on the other hand, allows the executed command to change the current environment. This is often useful when you use a script as a wrapper to set up your environment for the later execu- tion of some other command. For example, if you re working on several different projects at the sametime, you may find you need to invoke commands with different parameters, perhaps to invoke an olderversion of the compiler for maintaining an old program. 52Chapter

for file (Web site management) in fred* doif [ -d $file

Monday, July 30th, 2007

for file in fred* doif [ -d $file ]; thenbreak; fidoneecho first directory starting fred was $filerm -rf fred* exit 0The : CommandThe colon command is a null command. It s occasionally useful to simplify the logic of conditions, alias for true. Since it s built-in, :runs faster than true, though its output is also much less readable. You may see it used as a condition for whileloops; while :implements an infinite loop in place common while true. The :construct is also useful in the conditional setting of variables. For example, : ${var:=value} Without the :, the shell would try to evaluate $varas a command. #!/bin/shrm -f fredif [ -f fred ]; then: elseecho file fred did not existfiexit 0continueRather like the C statement of the same name, this command makes the enclosing for, while, or untilloop continue at the next iteration, with the loop variable taking the next value in the list. #!/bin/shrm -rf fred* echo > fred1In some, mostly older shell scripts, you may see the colon used at the start of a lineto introduce a comment, but modern scripts should always use # to start a commentline because this executes more efficiently.

Typical output from this (Web servers) script might be: $

Monday, July 30th, 2007

Typical output from this script might be: $ ./my_name Rick NeilOriginal parameters are Rick NeilIs your name Rick ? Enter yes or no: yesHi Rick, nice name$ How It WorksAs the script executes, the function yes_or_nois defined but not yet executed. In the ifstatement, thescript executes the function yes_or_no, passing the rest of the line as parameters to the function aftersubstituting the $1with the first parameter to the original script, Rick. The function uses these parame- ters, which are now stored in the positional parameters $1, $2, and so on, and returns a value to thecaller. Depending on the return value, the ifconstruct executes the appropriate statement. As we ve seen, the shell has a rich set of control structures and conditional statements. We need to learnsome of the commands that are built into the shell; then we ll be ready to tackle a real programmingproblem with no compiler in sight! CommandsYou can execute two types of commands from inside a shell script. There are normal commands that youcould also execute from the command prompt (called external commands), and there are built-in com- mands (called internal commands) that we mentioned earlier. Built-in commands are implemented internallyto the shell and can t be invoked as external programs. Most internal commands are, however, also pro- vided as standalone programs this requirement is part of the POSIX specification. It generally doesn tmatter if the command is internal or external, except that internal commands execute more efficiently. Here we ll cover only the main commands, both internal and external, that we use when we re program- ming scripts. As a Linux user, you probably know many other commands that are valid at the commandprompt. Always remember that you can use any of these in a script in addition to the built-in commandswe present here. breakWe use this for escaping from an enclosing for, while, or untilloop before the controlling conditionhas been met. You can give breakan additional numeric parameter, which is the number of loops tobreak out of. This can make scripts very hard to read, so we don t suggest you use it. By default, breakescapes a single level. #!/bin/shrm -rf fred* echo > fred1echo > fred2mkdir fred3echo > fred450Chapter

echo $sample_text} echo script starting echo $sample_textfooecho script (Web hosting rating)

Monday, July 30th, 2007

echo $sample_text} echo script starting echo $sample_textfooecho script ended echo $sample_textexit 0In the absence of a returncommand specifying a return value, a function returns the exit status of command executed. Try It Out Returning a ValueIn the next script, my_name, we show how parameters to a function are passed and how functions canreturn a trueor falseresult. You call this script with a parameter of the name you want to use in 1.After the shell header, we define the function yes_or_no: #!/bin/shyes_or_no() { echo Is your name $* ? while truedoecho -n Enter yes or no: read xcase $x iny | yes ) return 0;; n | no ) return 1;; * ) echo Answer yes or no esacdone} 2.Then the main part of the program begins: echo Original parameters are $* if yes_or_no $1 thenecho Hi $1, nice name elseecho Never mind fiexit 049ShellProgrammingb544977

Remote web server - Running the script will showscript startingFunction foo is

Sunday, July 29th, 2007

Running the script will showscript startingFunction foo is executingscript endingHow It WorksThis script starts executing at the top, so nothing is different there. But when it finds the foo() {con- struct, it knows that a function called foois being defined. It stores the fact that foorefers to a functionand continues executing after the matching }. When the single line foois executed, the shell knows toexecute the previously defined function. When this function completes, execution resumes at the lineafter the call to foo. You must always define a function before you can invoke it, a little like the Pascal style of function defi- nition before invocation, except that there are no forward declarations in the shell. This isn t a problem, because all scripts start executing at the top, so simply putting all the functions before the first call of anyfunction will always cause all functions to be defined before they can be invoked. When a function is invoked, the positional parameters to the script, $*, $@, $#,$1,$2, and so on arereplaced by the parameters to the function. That s how you read the parameters passed to the function. When the function finishes, they are restored to their previous values. We can make functions return numeric values using the returncommand. The usual way to make func- tions return strings is for the function to store the string in a variable, which can then be used after thefunction finishes. Alternatively, you can echoa string and catch the result, like this. foo () { echo JAY;} … result= $(foo) Note that you can declare local variables within shell functions by using the localkeyword. The vari- able is then only in scope within the function. Otherwise, the function can access the other shell vari- ables that are essentially global in scope. If a local variable has the same name as a global variable, itoverlays that variable, but only within the function. For example, we can make the following changes tothe preceding script to see this in action: #!/bin/shsample_text= global variable foo() { local sample_text= local variable echo Function foo is executing Some older shells may not restore the value of positional parameters after functionsexecute. It s wise not to rely on this behavior if you want your scripts to be portable. 48Chapter

Statement BlocksIf you want to use multiple statements (Apache web server)

Sunday, July 29th, 2007

Statement BlocksIf you want to use multiple statements in a place where only one is allowed, such as in an AND or you can do so by enclosing them in braces {}to make a statement block. For example, in the appli- cation presented later in this chapter, you ll see the following code: get_confirm && { grep -v $cdcatnum $tracks_file > $temp_filecat $temp_file > $tracks_fileechoadd_record_tracks} FunctionsYou can define functions in the shell and, if you write shell scripts of any size, you ll want to use them your code. As an alternative, you could break a large script into lots of smaller scripts, each of which performs asmall task. This has some drawbacks: Executing a second script from within a script is much slowerthan executing a function. It s more difficult to pass back results, and there can be a very large numberof small scripts. You should consider the smallest part of your script that sensibly stands alone and usethat as your measure of when to break a large script into a collection of smaller ones. If you re appalled at the idea of using the shell for large programs, remember that the FSF autoconfprogram and several Linux package installation programs are shell scripts. You can always guaranteethat a basic shell will be on a Linux system. In general, Linux and UNIX systems can t even boot with- out /bin/sh, never mind allowing users to log in, so you can be certain that your script will have ashell available to interpret it on a huge range of UNIX and Linux systems. To define a shell function, we simply write its name followed by empty parentheses and enclose thestatements in braces: function_name (){ statements} Try It Out A Simple FunctionLet s start with a really simple function: #!/bin/shfoo() { echo Function foo is executing } echo script starting fooecho script ended exit 047ShellProgrammingb544977

Starting at the left, each statement is executed. (Web site translator)

Saturday, July 28th, 2007

Starting at the left, each statement is executed. If it returns false, the next statement to the right is exe- cuted. This continues until a statement returns true, when no more statements are executed. The ||list is very similar to the &&list, except that the rules for executing the next statement are that theprevious statement must fail. Try It Out OR ListsCopy the previous example and change the shaded lines in the following listing: #!/bin/shrm -f file_oneif [ -f file_one ] || echo hello || echo there thenecho in if elseecho in else fiexit 0This will give you the outputhelloin ifHow It WorksThe first two lines simply set up the files for the rest of the script. The first command, [ -f file_one], fails because the file doesn t exist. The echostatement is then executed. Surprise, surprise, this returnstrue, and no more commands in the ||list are executed. The ifsucceeds because one of the commandsin the ||list (the echo) was true. The result of both of these constructs is the result of the last statement to be executed. These list-type constructs execute in a similar way to those in C when multiple conditions are beingtested. Only the minimum number of statements is executed to determine the result. Statements thatcan t affect the result are not executed. This is commonly referred to as short circuit evaluation. Combining these two constructs is a logician s heaven. Try out: [ -f file_one ] && command for true || command for falseThis will execute the first command if the test succeeds and the second command otherwise. It s alwaysbest to experiment with these more unusual lists, and in general you should use braces to force the orderof evaluation. 46Chapter

Starting at the left, each (Photo web hosting) statement is executed

Saturday, July 28th, 2007

Starting at the left, each statement is executed and, if it returns true, the next statement to the right This continues until a statement returns false, after which no more statements in the list The &&tests the condition of the preceding command. Each statement is executed independently, allowing us to mix many different commands in a single the following script shows. The AND list as a whole succeeds if all commands are executed success- fully, but it fails otherwise. Try It Out AND ListsIn the following script, we touchfile_one(to check whether it exists and create it if it doesn t) andthen remove file_two. Then the AND list tests for the existence of each of the files and echoes sometext in between. #!/bin/shtouch file_onerm -f file_twoif [ -f file_one ] && echo hello && [ -f file_two ] && echo there thenecho in if elseecho in else fiexit 0Try the script and you ll get the following result: helloin elseHow It WorksThe touchand rmcommands ensure that the files in the current directory are in a known state. The list then executes the [ -f file_one ]statement, which succeeds because we just made sure that existed. Because the previous statement succeeded, the echocommand is executed. This also suc- ceeds (echoalways returns true). The third test, [ -f file_two ]is executed. It fails because the exist. Because the last command failed, the final echostatement isn t executed. The result of list is falsebecause one of the commands in the list failed, so the ifstatement executes its elsecondition. The OR ListThe OR list construct allows us to execute a series of commands until one succeeds, then not execute The syntax isstatement1 ||statement2 ||statement3 ||…

Note that (Web hosting unlimited bandwidth) the ;;before esacis optional. Unlike C

Friday, July 27th, 2007

Note that the ;;before esacis optional. Unlike C programming, where leaving out a break is poorprogramming practice, leaving out the final ;;is no problem if the last case is the default because noother cases will be considered. To make the casematching more powerful, we could use something like this: [yY] | [Yy][Ee][Ss] ) This restricts the permitted letters while allowing a variety of answers and gives more control than the * wildcard. ListsSometimes we want to connect commands in a series. For instance, we may want several different condi- tions to be met before we execute a statement likeif [ -f this_file ]; thenif [ -f that_file ]; thenif [ -f the_other_file ]; thenecho All files present, and correct fififior you might want at least one of a series of conditions to be true: if [ -f this_file ]; thenfoo= True elif [ -f that_file ]; thenfoo= True elif [ -f the_other_file ]; thenfoo= True elsefoo= False fiif [ $foo = True ]; thenecho One of the files exists fi Although these can be implemented using multiple ifstatements, you can see that the results are awk- ward. The shell has a special pair of constructs for dealing with lists of commands: the AND list and theOR list. These are often used together, but we ll review their syntax separately. The AND ListThe AND list construct allows us to execute a series of commands, executing the next command only ifall the previous commands have succeeded. The syntax isstatement1 &&statement2 &&statement3 &&… 44Chapter