Introduction to Linux OS (IV) AUBG ICoSCIS Team Prof. Volin Karagiozov March, 09 – 10, 2013 SWU, Blagoevgrad The Shell • • • • • • Definitions, Reserved words, Shell Grammar Creating simple shell scripts Variables definition Shell expansion Built-in shell variables Flow control Definitions • • blank word A space or tab. A sequence of characters considered as a single unit by the shell. Also known as a token. • name A word consisting only of alphanumeric characters and underscores, and beginning with an alphabetic character or an underscore. Also referred to as an identifier. • metacharacter A character that, when unquoted, separates words. One of the following: | & ; ( ) < > space tab • control operator A token that performs a control function. It is one of the following symbols: || & && ; ;; ( ) | <newline> Reserved Words • Reserved words are words that have a special meaning to the shell. The following words are recognized as reserved when unquoted and either the first word of a simple command (see SHELL GRAMMAR below) or the third word of a case or for command: ! case do done elif else esac for function if in select then until while { } fi Shell Grammar • • • • • • • • • • • • • Simple commands|| Pipelines|| Lists Compound commands Comments Quoting || Parameters Shell variables Expansion Redirection|| Functions Aliases Job control || Creating a Simple Shell Script • A shell script is a file that contains commands to be executed by the shell. • Making a File Executable – use chmod $ chmod +x scriptname Example: $ cat > whoson date echo Users Currently Logged In who Ctrl+D $ whoson bash: whoson: command not found $ chmod u+x whoson Start whoson now! $ whoson $ ./whoson Does not work! WHY? Ways to run a shell script Command Separation and Grouping • Command separator - ; character • $ a; b; c (a,b,c - commands) • The \ character – when entering very long command line – quotes the New-line character • The | and & characters $a|b|c $a&b&c a and b in the background Commands separated by a ; are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed. | - pipeline symbol If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0. Example 1. Create files a, b and c which echo its names $ cat > a echo echo echo echo echo “aaaaaaaaaaaaaaaaaaaaaaaa” “aaaaaaaaaaaaaaaaaaaaaaaa” “aaaaaaaaaaaaaaaaaaaaaaaa” “aaaaaaaaaaaaaaaaaaaaaaaa” “aaaaaaaaaaaaaaaaaaaaaaaa” 3. ………………??? Ctrl+D 4. Execute now: $ ./a&./b&./c& 2. Now we will create files b and c using tr command: 5. Explain (comment) the output $ tr $ tr 'a' 'a' 'b' 'c' <a <a >b >c Processes • Process structure – parents, child and root Example: 1. $ ps –ef |more 2. $ ps -ef | grep your_user_name Discussion ….. Parent process forkes (spawns) a child, child may forks another child, etc. Variables • User-Created variables ( = ) $ person=alex $ echo $person NO spaces around = sign! • Removing variables – unset or $ person= • export command The read Command To accept the user input and store the input in variable – examples: $ cat read1 echo –n Go ahead: read firstline echo “You entered: $firstline” $ cat read3 echo -n Enter something: read word1 word2 word3 echo "Word 1 is: $word1" echo "Word 2 is: $word2" echo "Word 3 is: $word3" $ cat read2 echo –n Enter command: read command $command echo Thanks Create script files read1, read2 and read and execute the scripts. Explain (comment) the output! Expansion • Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: • • • • • • • brace expansion tilde expansion parameter and variable expansion command substitution arithmetic expansion word splitting, and pathname expansion. • The order of expansions is: brace expansion, tilde expansion, parameter, variable, command, and arithmetic substitution (done in a left-to-right fashion), word splitting, and pathname expansion. Tilde expansion • If a word begins with a tilde character (`~'), all of the characters preceding the first slash (or all characters, if there is no slash) are treated as a possible login name. If this login name is the null string, the tilde is replaced with the value of the parameter HOME. If HOME is unset, the home directory of the user executing the shell is substituted instead. • If a `+' follows the tilde, the value of PWD replaces the tilde and `+'. If a `-' follows, the value of OLDPWD is substituted. If the value following the tilde is a valid login name, the tilde and login name are replaced with the home directory associated with that name. If the name is invalid, or the tilde expansion fails, the word is unchanged. Command substitution • Command substitution allows the output of a command to replace the command name. There are two forms: $(command) or `command` • Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. • Command substitutions may be nested. To nest when using the old form, escape the inner backquotes with back slashes. If the substitution appears within double quotes, word splitting and pathname expansion are not performed on the results. Command substitution • Example $ cat dir dir=`pwd` echo You are using the $dir directory. ls –l $dir Create script file named dir and execute it. What does the script do? Explain! Built-in Shell Variables Built-in variables are automatically set by the shell and are typically used inside shell scripts. Built-in variables can make use of the variable substitution patterns shown above. Note that the $ is not actually part of the variable name, although the variable is always referenced this way. $# $$? $$ $! $0 $n Number of command-line arguments. Options currently in effect (arguments supplied to sh or to set). Exit value of last executed command. Process number of current process. Process number of last background command. First word; that is, command name. Individual arguments on command line (positional parameters). The Bourne shell allows only nine parameters to be referenced directly (n = 1-9); the Korn shell allows n to be greater than 9 if specified as ${n}. $* All arguments on command line ("$1 $2..."). "$@" All arguments on command line, individually quoted ("$1" "$2" ...). Name of Calling Program – stored in variable $0 Command Line arguments – stored in variables $1, $2, ……., $9 Example: $cat > display_args echo The command used is: $0 and the number of args is: $# echo The first five args are: $1 $2 $3 $4 $5 echo All args are: $* echo All args are: $@ Ctrl+D $ chmod +x display_args $ ./display_args a b c d e f g h I j k l m n o p r s t The shift command – promotes each of the command line arguments. $2 becomes $1, the third becomes the second, etc. Using $1-$9 you can access only the first 9 arguments. Shift makes available tenth command line argument by making it ninth. NO unshift command! Example: demo_shift: echo “arg1= $1 arg2=$2 arg3=$3” shift echo “arg1= $1 arg2=$2 arg3=$3” shift echo “arg1= $1 arg2=$2 arg3=$3” shift echo “arg1= $1 arg2=$2 arg3=$3” shift Create demo_shift file, make it executable and try it: $ demo_shift alice Helen jenny The set command - sets the values of the command line arguments Example: $ cat set_it set this is it echo $3 $2 $1 Example: $date $cat dateset set `date` echo $* echo echo “Argument 1: $1” echo “Argument 2: $2” echo “Argument 3: $3” echo “Argument 4: $4” echo echo $2 $3, $6 Create the file dateset and play with this script. Now try the command set without any parameters! $ ./set_it it is this Control Flow Commands – they include control structures: Simple two-way branching If statement Multiple branching Case statement For, While and Until statements If Then if test-command then commands fi Example: $cat if1 echo –n “word 1: “ read word1 echo –n “word 2: “ read word2 if test “$word1” = “$word2” then echo Match fi test test-command [ test-command ] ^ ^ If Then Else if test-command then commands else commands fi If Then Elif if test-command then commands elif test-command then commands else commands fi test test-command [ test-command ] ^ ^ Example: $cat if3 echo –n “word 1:” read word1 echo –n “word 2:” read word2 echo –n “word 2:” read word2 if [ “$word1” = ”$word2” –a ”$word2” = ”$word3” then echo “Match: words 1, 2 & 3” elif [ “$word1” = ”$word3” ] then echo “Match: words 1 & 3” elif [ “$word2” = ”$word3” ] then echo “Match: words 2 & 3” elif [ “$word1” = ”$word2” ] then echo “Match: words 1 & 2” else echo No match fi ] Flow Control Sometimes you want a script that will step through the command-line arguments one by one. (The "$@" parameter gives you all of them at once.) The Bourne shell for loop can do this. The for loop looks like this: for arg in list do ...handle $arg... done If you omit the in list , the loop steps through the command-line arguments. It puts the first command-line argument in arg (or whatever else you choose to call the shell variable), then executes the commands from do to done. Then it puts the next command-line argument in arg, does the loop... and so on... ending the loop after handling all the arguments. Example1a: (for – in) for person in Joe Leslie Edie Allan #argument-list: Joe Leslie Edie Allan do #loop-index: person echo "Dear $person," | cat - form_letter | lpr done Example1b: (for – in) for filename in "$@" do file $filename done Example2: (for) for args do echo $args done Example3: (for) if [ $# = then echo exit fi for i do grep done 0 ] “Usage: whos id ….” 1>&2 1 –i “$i” /etc/passwd Standard Input to a for Loop An obvious place to use a Bourne shell for loop is to step through a list of arguments - from the command line or a variable. But combine the loop with backquotes and cat , and the loop will step through the words on standard input. Here's an example: for x in `cat` do ...handle $x done Example If you want a for loop that stores several different shell variables and makes one pass through the loop for each set of variables (instead of one pass for each item, as a regular for loop does). This loop does the job: for bunch in "ellie file16" "donna file23" "steve file34" do # PUT FIRST WORD (USER) IN $1, SECOND (FILE) IN $2... set $bunch echo ”mail $1 < $2” done Looping Until a Command Succeeds (until) until test-command do commands done (true – done) (false – do commands) The until loop runs a command repeatedly until it succeeds. That is, if the command returns a non-zero status, the shell executes the body of the loop and then runs the loop control command again. Example1: $ cat sysmgr #!/bin/sh until who | grep "vkaragiozov " do sleep 60 done echo The Instructor just logged on. $ sh sysmgr & [1] 2345 ...time passes... AUBGIN\vkaragiozov pts/2 The Instructor just logged on. 2008-02-25 09:52 Looping Until a Command Fails (while) while test-command do commands done (false – done) (true – do commands) The while loop is the opposite of the until loop. A while loop runs a command and loops until the command fails (returns a non-zero status). The Break and Continue Commands To interrupt a for, while or until loop: break – transfer control to the statement after the done statement. continue – transfer control to the done statement and continues execution of the loop. Test String Values with Bourne Shell case Each time you type a command line at a shell prompt, you can see what happens and decide what command to run next. But a shell script needs to make decisions like that itself. A case statement helps the script make decisions. A case statement compares a string (usually taken from a shell or environment variable) to one or more patterns. The patterns can be simple strings (words, digits, etc.) or they can be case wildcard expressions. When the case finds a pattern that matches the string, it executes one or more commands. case test-string in Pattern-1) Commands-1 ;; Pattern-2) Commands-2 ;; Pattern-3) Commands-3 ;; esac Example: echo “Enter A, B, or C:” read letter case “$letter” in a|A) echo You entered A ;; b|B) echo You entered B ;; c|C) echo You entered C ;; esac