Shell Scripts: CS3411 Spring 2009
Shell Scripts: CS3411 Spring 2009
Revisiting execve(2)
NA M E execve - execute p rogram SYN O P SIS # lude <un t inc is d.h> in execve (const char *i ename, char *cons a [, t fl t rgv ] char * const envp[ ) ]; DESC RIPTION execve( executes the program po ted to by fl name. ) in ie fl iename must be e ther a b i inary executab , o a le r sc ip sta t r t ring wi a l o the f th ine f orm "# in erpre [a ] . ! t ter rg " In the l te case, the i at r nterpre er must be a va id t l pa thname fo an executab wh is not i se fa scr t r le ich t l ip , wh wil be invoked as in rpreter [a fl ich l te rg] iename. ...
CS3411
Shell Scripts
Suppose we have file named scr pt, protected 0755, that starts i with #!/b /sh in Line that starts with # is a comment to /bin/sh. The file scr iptis then a shell script. If first line does not start with #!, it is as if the first line were #! in sh. /b /
CS3411
Shell Scripts
CS3411
Shell Scripts
This processes the three files given as arguments to the script/command printps:
./printps elm.txt vi.ref msg
Usually only nine command line arguments can be accessed using positional parameters. The sh f i tcommand gives access to command line arguments greater than nine by shifting each of the arguments. The second argument ($2) becomes the first ($1), the third ($3) becomes the second ($2) and so on. This gives you access to the tenth command line argument by making it the ninth. The first argument is no longer available. Successive shift commands make additional arguments available. Note that there is no unsh f command to bring back it arguments that have been shifted through $1!
CS3411
Shell Scripts
In execution:
% ./shift_demo one two three four five six seven arg1=one arg2=two arg3=three arg1=two arg2=three arg3=four arg1=three arg2=four arg3=five arg1=four arg2=five arg3=six
CS3411
Shell Scripts
${3 -defau t : l }means $3, unless $3 is unset or null, then it means defau t. l
#!/bin/sh echo "arg1=$1 arg2=$2 arg3=${3:-dummy}" % ./default_demo a b c arg1=a arg2=b arg3=c % ./default_demo a b arg1=a arg2=b arg3=dummy % ./default_demo a b "" arg1=a arg2=b arg3=dummy
CS3411
Shell Scripts
CS3411
Shell Scripts
[jmayo]$./special.sh
# # string string $VAR $VAR
Shell Scripts
Subshells
( cmds ) Combines stdout and stderr of cmds into one stream
[jmayo]$ ./newshell.sh 2 2 11
Launches another instance of command processor Does not fork new process
CS3411
Shell Scripts
10
[jmayo]$ cat newshell2.sh #!/bin/sh echo First pid is $$ (echo Second pid is $$ ) echo ----------------------./echoPid.sh
[jmayo@]$
cat echoPid.sh
[jmayo]$ ./newshell2.sh First pid is 3249 Second pid is 3249 ----------------------Echo pid is 3251 [jmayo]$
CS3411
Shell Scripts
11
Variable Propagation
Variables defined in shell are not visible in the parent
[jmayo]$ cat prop.sh #!/bin/sh VAR=value echo "First value is <$VAR>" (echo "Sub value is <$VAR>"; VAR=newvalue; \ echo "Sub new value is <$VAR>") echo "Final value is <$VAR>"
[jmayo]$ ./prop.sh First value is <value> Sub value is <value> Sub new value is <newvalue> Final value is <value>
CS3411 Shell Scripts 12
Export
Export moves variable definition from shell to environment Other programs may access
[jmayo]$
bash bash-3.00$ VAR=value; ./echoVar.sh Echovar has value bash-3.00$ export VAR=value; ./echoVar.sh Echovar has value value bash-3.00$ exit [jmayo@asimov ~/codeExamples]$ setenv VAR value; ./echoVar.sh Echovar has value value [jmayo@asimov ~/codeExamples]$
CS3411
Shell Scripts
13
Reading Input
Can read from standard input into a shell script with the read command:
% cat readin.sh echo "Please enter your name:" read name echo "Hi, $name % ./readin.sh Please enter your name: phil Hi, phil
CS3411
Shell Scripts
14
If there is more than one word in the input, each word can be assigned to a different variable. Any words left over are assigned to the last named variable. For example:
% cat readin2.sh echo "Please enter your surname" echo "followed by your first name:" read name1 name2 echo "Hi, $name2 $name1 % ./readin2.sh Please enter your surname followed by your first name: Nimble jack b Hi, jack b nimble
CS3411
Shell Scripts
15
CS3411
Shell Scripts
16
The i fCommand
The i fstatement uses the exit status of the given command and conditionally executes the statements following. The general syntax is:
if test then commands (if condition is true) else commands (if condition is false) fi
The lexemes then, e lse and f iare shell reserved words and as such are only recognized after a newline or ; (semicolon). Make sure that you end each if construct with a f istatement.
CS3411
Shell Scripts
17
The elfstatement can be used as shorthand for an else if i statement. For example:
if ... then ... elif ... ... fi fi
CS3411
Shell Scripts
18
An example:
% cat checkon.sh if finger | grep -s $1 > /dev/null then echo $1 is logged in else echo $1 not available fi % ./checkon.sh park park is logged in % ./checkon.sh sharon sharon not available
CS3411
Shell Scripts
19
The first command, cmd1, is executed and its exit status examined. Only if cmd1 succeeds is cmd2 executed. This is shorthand for:
if cmd1 then cmd2 fi
CS3411
Shell Scripts
20
To check for a Unix domain socket in the current working directory (a socket in the Unix domain, unlike the IPv4 domain, shows up as a directory entry):
% cat checkforsocket.sh #!/bin/sh # usage: checkforsocket.sh { ls -l | grep -s \^s > /dev/null ; } && echo found a socket % ./checkforsocket.sh % cd .. % ls -l SOCKET_0 srwxrwxrwx 1 kearns wheel 0 Apr 2 06:00 SOCKET_0 % ~/courses.d/315/checkforsocket.sh found a socket
CS3411
Shell Scripts
21
The | |Operator
You can use the | |operator to execute a command and, if it fails, execute the next command in the command list. For example:
cmd1 || cmd2
cmd1 is executed and its exit status examined. If cmd1 fails then cmd2 is executed. This is shorthand for:
cmd1 if test $? -ne 0 then cmd2 fi
CS3411
Shell Scripts
22
In my console window:
hi % ./writemail.sh root hi write: root not logged in
In roots inbox:
From: Jean Mayo <[email protected]> Date: Wed, 3 Apr 1996 17:25:05 -0500 (EST) To: [email protected] hi
CS3411
Shell Scripts
23
Commonly-used alternative syntax for test, but with exactly the same semantics:
% cat testargs.sh #!/bin/sh # usage: testargs.sh arg1 arg2 ... if [ $# -gt 2 ] then echo "more than 2 args" else echo "less than or equal to 2 args" fi
CS3411
Shell Scripts
26