Friday, February 17, 2012

Linux shell script


Introduction

What is a shell script commands you can use a combination of shell collecting and made ​​a batch (batch) is a file . Linux, several instructions in the pipe (pipe), redirect (redirection), filters (filter) and so you'll be able to get the results you want to connect is . In this way, tied with a combination of instruction, if it is used repeatedly as a shell script , that can easily be used to create a single command.

Script that was Interpreter (interpreter) and interpreted by / is a program that runs . Street to use some kind of interpreter for the name is determined on whether any scripts so . shell scripts , Perl (Perl) scripts , Tcl / Tk script interpreter used by names such as can be seen. shell script to use a shell script points to an interpreter . also uses some shell Street Therefore, this (bourne) shell scripts , C shell scripts , Korn ( Korn) shell scripts , TC are divided into a shell script .

In this series of shell scripts in the underlying will look at this shell script . Bourne shell script used by the functionality and syntax is different sweleseodo support . Therefore, the actual will be used when using a different shell . I bash 1.14 0.7 will use the description .


What a shell script ?

Knowingly or unknowingly, we use a lot of shell scripts . swelseukeuripteuinga So What ? way, trying to check file and grep command would look to . my results are as follows in the system .

$ (Cd / bin; file * | grep "shell script")
false: Bourne shell script text
igawk: Bourne shell script text
remadmin: Bourne shell script text
true: Bourne shell script text
$ (Cd / usr / bin; file * | grep "shell script")
anytopnm: Bourne shell script text
apropos: Bourne shell script text
audiocompose: C shell script text
audiosend: C shell script text
autoconf: Bourne shell script text
autoheader: Bourne shell script text
autoreconf: Bourne shell script text
autoupdate: Bourne shell script text
bash2bug: Bourne shell script text
bashbug: Bourne shell script text
batch: Bourne shell script text
bdftops: Bourne shell script text
bzless: Bourne shell script text
......
whatis: Bourne shell script text
wv-incconfig: Bourne shell script text
wv-libconfig: Bourne shell script text
xbm2ikon: Bourne shell script text
xbmcut48: Bourne shell script text
xbmsize48: Bourne shell script text
zcmp: Bourne shell script text
zdiff: Bourne shell script text
zforce: Bourne shell script text
zgrep: Bourne shell script text
zipgrep: Bourne shell script text
zless: Bourne shell script text
zmore: Bourne shell script text
znew: Bourne shell script text

'll Follow the above command, identified as false, true, apropos, netscape, nohup, pdf2ps, ps2pdf, whatis, zgrep, zless , and many can be seen that there is a shell script .


To create a shell script

One of the characteristics of the script in text format, because the content can be viewed as general editor . any of the above script to find the cat, vi, emacs , etc. See : multiple commands and scripts to check that the grammar is a combination of can .

The first line of the script is always #! should start with . #! then run this script and then run the option to specify an interpreter . shell script #! / bin / sh, #! / bin / csh, #! / bin / bash, #! / bin / ksh, #! / bin / tcsh as the shell. Put the absolute path . old tradition by #!ten thousand if you write you #! / bin / sh is recognized as .
Therefore, when writing a shell script the first line #! / bin / sh or #! depends on you .

Now, on the basis of the previous example, a simple 'findscript' Let us write a shell script : The script / bin, / usr / bin shows a shell script to find .

$ Cat findscript
#! / Bin / sh #
# Findscript: / bin, / usr / bin to find a shell script in .
#

(Cd / bin; file * | grep "shell script")
(Cd / usr / bin; file * | grep "shell script")
$ Chmod + x findscript.sh
$. / Findscript.sh

cat or another editor to create and use as above , give permission to the executable . Then if another program is running as . shown above is basically a shell script is a set of shell commands that are available . here In addition, shell, shell script that can be used to provide its own grammar .


The exit status (Exit status)

Each commands execute correctly after normal shutdown ( success / true ) , or , an execution error or an interrupt caused by interrupted for reasons such as abnormally terminated ( fail / false ) can be . the success or failure of the command exit status to the Al can be usually 0 indicates success , 0 A non-zero value indicates failure . shell command is executed before the failure hayeotneunjireul sure success ? variable is saved in the .

$ Who | grep root
$ Echo $?
A
$ Who | grep hermes44
hermes44: 0 Sep 16 11:34
hermes44 pts / 0 Sep 16 11:36
hermes44 pts / 1 Sep 16 14:07
$ Echo $?
0
$ False; echo $?
A
$ True; echo $?
0

false command always 1, and returns an exit status of failure and true command always 0, exit status is returned for success .

In the shell script exit using the exit status and exit the script can return . exit a shell script to exit when using only the last executed command returns an exit status , exit < number > you quit and < number > shell will return a value .

$ Cat return_exit
#! / Bin / sh
#
# Return_exit: < factor > exit status value of
# will return .
#

if [$ #-eq 0]
then
exit
else
exit $ 1
fi
$. / Return_exit; echo $?
0
$. / Return_exit 8; echo $?
8

if the branch is in accordance with the conditional expression syntax .
The format is as follows .

if the conditional expression
then
Commands
[Elif conditional
then
Commands ]
[Else
Commands ]
fi

if the conditional expression is true , that is 0 if the function returns then perform the following command, and , if false , ie 0 if returns a nonzero value ( usually one is ) else to perform the following command . elif that if the conditional expression becomes false if the new branch is a conditional expression is checked again . elif or else statements can be omitted . fi The if statements indicate the end .(Fi The if is written upside down :-))

In the above example script if the conditional statement [$ #-eq 0] number of arguments of the script ($ #), a 0 is equal to (-eq) is to check . factor if there is no exit command to perform and last performed exit status of the conditional expression of 0 is returned to . if there are any arguments else in the syntax of the value of the first argument ($ 1) returns the exit status .

Do shell script receives an interrupt in the middle of which may terminate abnormally . In this case, the temporary use such as deleting a file will not be able to perform cleanup operations . to avoid this trap is the syntax . types are as follows: .

trap ' commands '[ signal numbers ]

The interrupt signal number of_exception . This number kill-l If you can see . signal number 0 if you write a shell script shows when the normal shutdown .

Oh, you do shell script raeui loop remains on the screen, the text will be displayed . used here while would flow into an infinite loop .loop, I'll back for . exit to Ctrl + C (SIGINT, 2) press Although the first trap will print messages by syntax .
Ctrl + \ (SINQUIT, 3) Press the script will exit .

$ Kill -1

1) SIGHUP
2) SIGINT
3) SIGQUIT
4) SIGILL

5) SIGTRAP
6) SIGIOT
7) SIGBUS
8) SIGFPE

9) SIGKILL
10) SIGUSR1
11) SIGSEGV
12) SIGUSR2

13) SIGPIPE
14) SIGALRM
15) SIGTERM
16) SIGCHLD

17) SIGCONT
18) SIGSTOP
19) SIGTSTP
20) SIGTTIN

21) SIGTTOU
22) SIGURG
23) SIGXCPU
24) SIGXFSZ

25) SIGVTALRM
26) SIGPROF
27) SIGWINCH
28) SIGIO

29) SIGPWR


$ Cat trap_exit
#! / Bin / sh
#
# Trap_exit: trap test
#

trap 'echo basename $ 0: signal catch' 1 2 15
trap 'echo script exit; exit' 3

while:
do
echo loop
done
$. / Trap_exit


Command-line arguments (Command-line argument)

In a shell script up to 9 can receive command line arguments : the value $ 1 to $ 9 is saved in . ( The latest shell may be more arguments : $ {10} and is the same type .) $ 0 in the path of running a shell script is stored . In addition, as we saw briefly above $ #is the number of parameters is stored .

Script during the shift take note of the datavolume make use . shift of the $ 1 argument to eliminate the number of each factor adecreases by . that $ 2 is $ 1, $ 3 for $ 2, $ 4 for $ 3 and is the same way .

#! / Bin / sh
#
# Prarg: three arguments are the output .
#

prog = basename $ 0

if [$ #-eq 3]
then
echo "Script $ prog path: $ 0"
echo "Arg1: $ 1"
echo "Arg2: $ 2"
shift
echo "Arg3: $ 2"
else
echo "Usage: $ $ prog arg1 arg2 arg3"
exit
fi
$. / Prog es 34
Usage: $ prarg arg1 arg2 arg3
$. / Prog 28 ksl 9
Script prarg path:. / Prarg
Arg1: 28
Arg2: ksl
Arg3: 9

So shift after the third argument is a $ 2 becomes . the $ # value a gives .

All the argument "$ @", $ * is stored in . "$ @" at the command line using the quotation marks, but it still applies , $ * in quotes does not apply to them . quotes from the shell to use, depending on the presence of special characters - spaces , tabs ,, ', ",' etc. - interpret the decision is whether . the issues regarding use of the shell, because I will not learn any more .

$ $ in the current shell script process ID is stored . This command-line arguments, but not create temporary files in the same case is used yuyunghage .


Loop (Loop)

That can be used in shell scripts there are three kinds of loops .

while conditional
do
Commands
done

while loop, while the conditional expression is true do ~ done between the command to perform .

$ Cat arg-while
#! / Bin / sh
#
# Arg-while: prints all arguments .
#

echo Argument number: $ #
while [$ #-gt 0]
do
echo $ 1
shift
done
$. / Arg-whilel 1 2 3 4
Argument number: 4
A
2
3
4

until the conditional expression
do
Commands
done

until the loop until the conditional expression is true, do ~ done between the command to perform .

$ Cat arg-until
#! / Bin / sh
#
# Arg-until: prints all arguments .
#

echo Argument number: $ #
until [$ #-eq 0]
do
echo $ 1
shift
done
$. / Arg-until 1 2 3 4
Argument number: 4
A
2
3
4

for variable in [ string list ]
do
Commands
done

$ Cat arg-for
#
! / Bin / sh
#
# Arg-for: @ arguments in front of the argument is printed .
#
echo Argument number: $ #
for arg
do
if [$ arg = @]
then
break
fi
echo $ arg
done
$. / Arg-for 1 2 @ 3 2 4 6
Argument number: 7
A
2

for a list of string values ​​of the loop for a variable is assigned to do ~ done between the command to perform . in part will be used if you omit the command line arguments . break you exit the loop .

Although the non-loop C in the switch that serves a similar case is the syntax .
case of the format is as follows .

case variable in
Pattern 1) commands ;
Pattern 2) commands ;
*) commands ;
esac

Sugapeul pattern changes a while since bigyohaega If you have a pattern that corresponds to carrying out the corresponding command. ; the end of the command corresponding to the pattern indicates esac the (case is written upside down .) case indicates the end of the statement . that if there is a pattern * the pattern will perform the command . patterns available from the shell Wild cards (*,?), regular expressions , strings , variables can come .

$ Cat check-flag
#! / Bin / sh
#
# Check_flag: by examining the arguments flag to turn on .
#

aflag = 0
bflag = 0

for arg
do
case $ arg in
-A) aflag = 1;;
-B) bflag = 1;;
*) Echo "Usage:` basename $ 0 `[-a] [-b]" 1> & 2
exit 1;;
esac
done

echo aflag = $ aflag bflag = $ bflag
$. / Check-flag
aflag = 0 bflag = 0
$. / Check-flag-a
aflag = 1 bflag = 0
$. / Check-flag-a-b
aflag = 1 bflag = 1


Conditional

if, while, until the conditional expression syntax is used . conditional expression syntax that is the result of true and false : true if the conditional expression 0Returns , false if one is returned . conditional expression is as follows .

test meals
[ expression ]
:

Pailsik expression , munjayeolsik , the formula can be divided into the three types . : Always show chamimeul . while, until you create an infinite loop is used .

File, which file to examine the properties of expression that has the following types .

-B file : True if file is a block device file
-C file : True if file is a character device file
-D file : True if the file is a directory
-E file : True if file exists
-F file : True if file is a regular file
-L file : True if file is a symbolic link
-P file : the file named (named) True if the pipe
-S file : True if file is a socket
-R file : True if file is readable
-S file : the file size of 0 is greater than the true
-W file : True if file is writable
-X file : True if the file is executable
File 1-nt File 2: File 1 The file 2 is a newer file True
File 1-ot file 2: file a this file 2 file is older than the true
File 1-ef File 2: File 1 and File 2 is the same file, so

The expression for the string is a string comparison .

-Z string : the string length of 0 if the true
-N string : a character with a length of 0 If it is not true
String a = string 2: String 1 and String 2 have the same true
String s = string 2: String 1 and String 2 is very different from

The formula compares the numeric values ​​. a positive integer , negative integer , zero, variables may be coming .

Value 1-eq value 2: Value 1 = Value 2
Value 1-ne value 2: Value 1! = value 2
Value 1-lt value 2: Value 1 < value 2
Value 1-le value 2: Value 1 <= value 2
Value 1-gt value 2: Value 1> Value 2
Value 1-ge value 2: Value 1> = value 2

In addition, the following expression for the entire operation is possible .

! expression : negative for the expression (not)
Equation 1-a Equation 2: Equation 1 and Equation 2 for the intersection (and)
Equation 1-o Equation 2: Equation 1 and Equation 2 for the disjunction (or)

Standard input and output

The standard output from the whole article (stdout) to the output in echo command - that serve as an external program echo here, but the echo of the shell embedded (built-in) is a command . - were used . So, the standard input (stdin) to receive user input method ?standard input and stored in a variable that receives the read command has .

$ Cat. / Stdio
#! / Bin / sh
#
# Stdio: take the standard input to standard output is displayed .
#

echo-n "Type the filename:"
read filename

if [-e $ filename]
then
echo $ filename exists.
else
echo $ filename doesn \ 't exist.
fi
$. / Stdio
Type the filename: / dev/fd0
/ Dev/fd0 exists.
$. / Stdio
Type the filename: / dev/fd0. / Stdio
. / Stdio: [: / dev/fd0: binary operator expected
/ Dev/fd0. / Stdio doesn't exist.

stdio as in the example read a line of standard input and all filename put in the variable . ( terminated by a line, hit enter .) , but if the above , have a dog, a number of inputs can cause problems . both a space-separated list of file names when you enter each one separately, rather than being saved filename Because of the variable entering the if conditional is a failure . In this case, only the first receives and processes the input file name and you want to ignore the rest ? read the following if you specify multiple variables are : the standard input into a space - space and tab - delimited distinguished and values ​​of each read , and then click on the specified variable will be filled . the last variable in the rest of the remaining input everyone goes there .

$ Cat ./stdio2
#! / Bin / sh
#
# Stdio2: take the standard input to standard output is displayed .
#

echo-n "Type the filename:"
read filename1 filename2 dummy

for fn in $ filename1 $ filename2
do
if [-e $ fn]
then
echo $ fn exists.
else
echo $ fn doesn \ 't exist.
fi
done

echo Ignore $ dummy
$ ./stdio2
Type the filename: / dev/hda1 / etc / bashrc / bin / sh / bin / ls
/ Dev/hda1 exists.
/ Etc / bashrc exists.
Ignore / bin / sh / bin / ls

In other words , stdio2 example of a space-delimited input / dev/hda1 the filename1 in , / etc / bashrc the filenam2 in the / bin / sh / bin / ls the dummy will be put in .
If you get cancer, such as enter a phone number from being displayed on the screen, while the keyboard - so that the input is output to the screen echo says . - To prevent the stty program by using the echo will get rid of . should be restored later . script echo does not restore again in case you must shut down abnormally trap syntax should be .

$ Cat pswd
#! / Bin / sh
#
# Pswd: Enter the password receives .
#

trap 'stty echo; exit' 0 1 2 3 15

echo-n "Enter password:"
stty-echo
read password
stty echo
echo

echo "Your password is $ password"


Redirection (Redirection)

The shell, we <,>, >> using the standard input and output redirection (redirection) can be .
Such a thing is possible even on a shell script . exec is to use .

$ Cat redirect
#! / Bin / sh
#
# Redirect: standard input is redirected to a file .
#

temp = / tmp / delme $ $
# $ $ of the current process id value passes .
echo "This is line1.
This is line2.
This is line3. "> $ Temp
exec <$ temp
read line; echo $ line
read line; echo $ line
read line; echo $ line
$. / Redirect
This is line1.
This is line2.
This is line3.

redirect example, the exec command by the standard input / tmp / delme $ $ has been redirected to a file read command input from the file will be a line . the shell in each standard input redirection , standard output , standard error, the file descriptor 0, 1, 2, which corresponds to . else 3-9 until the descriptor is available .

$ Cat fredirect
#! / Bin / sh
#
# Fredirct: Changing the dynamic redirection
#

outfile = fredirect.out

exec 3 <& 1
# standard output, and three times the file descriptor matches .
# standard output three times by saving the file descriptor of the role in

/ Bin / rm-f $ outfile

while
echo-n "Enter command or CTRL-D to quit:"
read cmd
do
exec >> $ outfile
# standard output fredirect.out file redirection
echo $ cmd
exec> & 3
# file, converted to restore it back to the standard output
done
$. / Fredirect
Enter command or CTRL-D to quit: 21
Enter command or CTRL-D to quit: 234
Enter command or CTRL-D to quit: 2
Enter command or CTRL-D to quit: sjf
Enter command or CTRL-D to quit: sd
Enter command or CTRL-D to quit: kd
Enter command or CTRL-D to quit:
$ Cat fredirect.out
21
234
2
sjf
sd
kd

while, until, for, if, case statements, the last in line - done, fi, esac back - redirect by specifying its syntax can be changed only within the input and output . the syntax when you restore the original are brought out .

$ Cat bredirect
#! / Bin / sh
#
# Bredirct: redirection is only a particular phrase .
#

for arg
do
echo $ arg
done> bredirect.out 2> / tmp / bredirect.err

# error output to standard error, and delete files temporary error .
if [-s bredirect.err]
then
/ Bin / cat / tmp / bredirect.err 1> & 2
fi
/ Bin / rm-f / tmp / bredirect.err
$. / Bredirect 1 2 3 45
$ Cat. / Bredirect.out
A
2
3
45


Path

Elctron Microscopy (SEM) treat the shell script when a file pathname may need to operate . usually pathname " directory name /filename ' is in the form . This user's input or environment variables obtained through the path and filename in the directory name is to split basename and dirname programs are called .

basename < path >

Passes only the filename from the path . this time, the files do not actually need to exist .

basename < path > < extension >

Eliminates part of the filename extension is specified in .

dirname < path >

In the directory portion of the path passes .

$ Basename / home / httpd / index.html
index.html
$ Basename / home / httpd / index.html. Html
index
$ Dirname / home / httpd / index.html
/ Home / httpd


Calculation formula : expr

Basic script because it handles all values ​​as strings of numeric values ​​calculated using the formula to the expr program must be used .

expr factor 1 operator factor 2 [ operator factor 3.]

Is the numeric value or a string can be , the operator equation operators , relational operators , logical operators, there are three types .factors must be between the operator must be separated by a space . expr The result is 0 or not a null exit status is two or 0 is . 0 ornull if a 1 and a formula is not valid if the two are .

Formula to support operators +, -, *, /,% have , a common position follows the ranking operation . operation priority can also use parentheses to change . *, (,) to the shell because it is used specifically to use in the formula \ should be used with . formula comes when the operator two factors must be an integer formula is the output of the calculation results .

Three + five $ expr \ * two
13
$ Expr \ (3 + 5 \ ) \ * two
16
$ Echo $ 1
A
$ Expr $ i + 1
2


That supports relational operators =, =,>,> =, <, <= have ,> and < a \ must be used with . comparison is true, one is output , is false, then 0 is the output : At this time a constant factor , real , string, all can come .

$ Echo $ USER
hermes44
$ Expr $ USER = hermes44
A
$ Expr three \ > 5
0
4.5 $ expr \ <= 4.5
A

The logical operators 3 There are a . |, &,: is . each OR, AND, represents a regular expression search | and & should be used with the .

· | the OR is : factor 1 and factor 2 are both 0 factor two or one , otherwise output 0 to output .
and the AND is . factor a two 0 arguments two or one is output , otherwise the factor 2 is the output .
· : the regex (regular expression) is to navigate . argument one coming any string , factor 2 comes in the regular expression . factor afactor in the two to find a pattern that corresponds to a given regular expression . factor 2 and \ ( and \ ) as a fill it with a pattern corresponding to the arguments in parentheses a portion of the output in the absence of parentheses, the number is output to match the pattern ( regular expression format for information about the scope of this article will be omitted because of proceeding ).

$ Echo $ 1
A
$ Expr $ I \ > 5 \ | $ I + one
2
$ Expr $ I \ <5 \ & $ I + one
A
$ Export d = `date`; echo $ d
Mon Oct 10 00:53:04 KST 1999
$ Expr "$ d": '. *'
28
$ Expr "$ D": ' \ (. * \ ) '
Mon Oct 18 00:53:04 KST 1999
$ Expr "$ d": '[a-zA-Z] *'
3
$ Expr "$ D": ' \ ([are-zA-Z] * \ ) '
Mon


Multiple programs with a lot of scripts is to write the script, the following may occur if the .
The same behavior, the other name of the program . For example, a document editor, ex, vi, view the name is different, but all the same programs . But what in the name slightly different behavior depending on execution . ex begins with a line editor mode , vi will start with the screen editor mode . view and open the file in read-only mode .
Other programs, but a lot of overlap . For example, jdk package containing java, javac, javadoc, jar, jdb, appletview et all . javawrapperscript is linked to . . Javawrapper set up the Java environment and run the program gives the corresponding .
Parts that are common in such cases, if grouped together to give as well as saving disk space , coding can reduce the effort and , for each common part can be consistent . a shell script that is part of the common running processes and the name of the program to inspect the processing corresponding to each .
I created a script for the intersection of the core . Each program creates a key with a link to the script : the script to handle the common parts of the name of the program , $ 0 for each program, the report attempts to do .

$ Cat sc_core
#! / Bin / sh
#
# Sc_core: to handle the overlap integral part
#

echo Setup the Environments and Flags

case "$ 0" in
* Sc1)
echo Excute sc1;;
* Sc2)
echo Excute sc2;;
*)
echo Invalid commnad!
exit 1;;
esac
$ Ln-s sc_core sc1
$ Ln-s sc_core sc2
$ ./sc1
Setup the Environments and Flags
Excute sc1
$ ./sc2
Setup the Environments and Flags
Excute sc2

When you run the file, find the name sc_core example, as shown in the '* Filename ' how to use patterns and basename programs are also available .

$ Cat jc_core
#! / Bin / sh
#
# Jc_core: basename another way by
#

jcpath = '/ usr / local / bin'
jcprogram = `basename $ 0`

echo Setup the Environments and Flags

case "$ jcprogram" in
jcc)
echo Excute jcc;;
jdb)
echo Excute jdb;;
*)
echo "$ jcpath / $ jcprogram";;
esac
$ Ln-s jc_core jcc
$ Ln-s jc_core jdb
$ Ln-s jc_core jzip

$. / Jcc
Setup the Environments and Flags
Excute jcc
$. / Jdb
Setup the Environments and Flags
Excute jdb
$. / Jzip
Setup the Environments and Flags
/ Usr / local / bin / jzip 

Debugging

Through the whole story about a simple shell script, we were able to write now written to the next step on how to debug a shell script will be discussed . program that can be created without an error at one time not more than a genius programmer What is debugging code to increase stability and perfection is an essential task . In addition, in most cases , more than anything to write code that takes a lot of time debugging is twelve . usually in the Linux development environment, C If you've written a program with debugging tools gdbwill use . but gdb debugging earlier the best way around the code printf reported results by adding a run would be to identify problems. shell script, because it does not even exist any debugger echo debug using it is common to : But then how to do this in addition I will show you how you can use .


Optional features a shell

Shell itself, which is used for debugging command-line options are . -V in order to perform the reading portion of the shell script to screen prints . -X of the read part one part shows the actual execution . These results stderr output to the next in one of three ways you can use .

The first line of shell script, specify the options are as follows .
#! / Bin / sh-xv

, Without modifying the source to run once, run the following script .
$ Sh-xv [ script name ]

Only part of the script, not the whole to use this feature you are trying to use the following section is added in front .
set-xv

· To eliminate this feature, add the following to be necessary since .
set + xv

The first example in the article that dealt'll explain how to use them again .

As you can guess when prarg script takes three arguments, the input to output is a very simple script . Elctron Microscopy (SEM) Let's try the second method .

$ Cat. / Prarg
#! / Bin / sh
#
# Prarg: argument is the output .
#

prog = `basename $ 0`

if [$ #-eq 3]
then
echo "Script $ prog path: $ 0"
echo "Arg1: $ 1"
echo "Arg2: $ 2"
shift
echo "Arg3: $ 2"
else
echo "Usage: $ $ prog arg1 arg2 arg3"
exit 1
fi
$. / Prarg 1 2 3
Script prarg path:. / Prarg
Arg1: 1
Arg2: 2
Arg3: 3
$ Sh-x. / Prarg 1 2 3
+ + Basename. / Prarg
+ Prog = prarg
+ [3-eq 3]
+ Echo Script prarg path:. / Prarg
Script prarg path:. / Prarg
+ Echo Arg1: 1
Arg1: 1
+ Echo Arg2: 2
Arg2: 2
+ Shift
+ Echo Arg3: 3
Arg3: 3
$ Sh-xv. / Prarg 1 2 3
#! / Bin / sh
#
# Prarg: argument is the output .
#

prog = `basename $ 0`
basename $ 0
+ + Basename. / Prarg
+ Prog = prarg

if [$ #-eq 3]
then
echo "Script $ prog path: $ 0"
echo "Arg1: $ 1"
echo "Arg2: $ 2"
shift
echo "Arg3: $ 2"
else
echo "Usage: $ $ prog arg1 arg2 arg3"
exit 1
fi
+ [3-eq 3]
+ Echo Script prarg path:. / Prarg
Script prarg path:. / Prarg
+ Echo Arg1: 1
Arg1: 1
+ Echo Arg2: 2
Arg2: 2
+ Shift
+ Echo Arg3: 3
Arg3: 3

-X option only when you need to run a script that runs on only part of shows . + to run the shell portion , + +, the other external program ( the shell to execute external programs .) means that part running . -V option to run as the script shows the portion read . if, for, while, case , and reads the entire block, the block at a time because it performs, such as in the example above would result .output, the script execution and debugging output for the results to the screen looks like this may seem Electronics stdout as , the latterstderr would be displayed as . Therefore, in order to redirect the output to a file should be executed as follows .

$ Sh-xv [ script name ]> [ filename ] 2> & 1

2> & 1 for stderr (2) the results of stdout (1) and is redirected to the same place .

The results of an inquiry to check the run -e options can be . -E the -x output by the execution of the executable statements results 0non-zero ie , failure to return the case of a shell script to exit . But while, until, if you use conditional statements or &&, | |,! included in an executable statement that two -e is not effective .
Using the -x,-v the same as if you were using .

$ Cat ./stdio3
#! / Bin / sh
#
# Stdio3: take the standard input to standard output is displayed .
#

filename = `line`

if [-e $ filename]
then
echo $ filename exists.
else
echo $ filename doesn \ 't exist.
fi
$ ./stdio3
./stdio3: line: command not found
exists.
$ Sh-x ./stdio3
+ + Line
./stdio3: line: command not found
+ Filename =
+ [-E]
+ Echo exists.
exists.
$ Sh-ev ./stdio3
+ + Line
./stdio3: line: command not found
+ Filename =

-E option is run and if the previous execution of the statement to fail if executed exit can be seen that before .


Conditional

In a conditional expression, similar to the general if you use a compiled language, I do not really have, if an error occurs .

In the formula you want to check conditional test variable does not exist or if the value is not set to an error occurs . ie , in the following conditional

if ["$ count"-eq 3]
count value of the variable does not exist or is not set, the interpretation is as follows:

if [""-eq 3]
The following error occurs .

[: Integer expression expected before-eq
To prevent this, change the above formula as follows .

if ["0 $ count"-eq 3]
In this case, when the above error situation 0 , and it simply returns the count variable is a three days if the 03 is to return operation is performed without error, the conditional expression .

Conditional statements in the test string to test string used in the conditional expression if the error occurs kiwodeuil . namely , that the string -eq,-ne,-gt,-r,-w,-z,-f , and geotdeulil s time . this case, right before you want to compare a string by adding characters and things like that before, so that the conditional expression will come from .

if ["$ op" =-gt]
Changes are as follows .

if ["Z $ op" = Z-gt]
In front of the -e option, as we saw when discussing the executable statements in a shell script that fails, the script is not interrupted . (To stop the -e option should ) , but that break the illusion wrong if you write the script has . the following cases it may be better in a fatal outcome .

$ Cat clean
#! / Bin / sh

tempdir = '/ tmp / usr / tmp / var / tmp'

for dir in $ tempdir
do
cd $ dir
rm-rf *
done

echo "Cleanup done!"

CD $ dir ' and then run to fail even if the writers 'rm-rf *' is executed . cd to fail if the thought does not erase all the contents of the directory may be better results . Thus, in order to avoid this problem, run the following statement when it comes to the fatal execution of the previous statement should not run if it fails . | | by the condition cd and change the execute statement .

cd $ dir | | exit

In this case, the | | previous cd fail, exit is executed to prevent further progress . cd is successful, the | | conditional expression is always true, because | | the right of the exit is not executed . In the above example, exit instead continue it is also okay .


Variable to determine

Interactively in a shell script, there was a way to determine the variables . that features a shell script code that is inserted in the middle is a way .

while echo-n "ENTER variable name you want to know are; \
just ENTER to quit: "
read var
do
case "$ var" in
"" ) break;;
*) Eval echo \ $ $ var;;
esac
done

The trace (trace) confirm the values ​​of the variables used in the previous code can be seen .

$ Cat trace
#! / Bin / sh
#
# Trace: trace code with variables watch that show .
#

dir = `dirname $ 0`
file = `basename $ 0`

count = 0

for arg in $ *
do
count = `expr $ count + 1`

# Trace code
while echo-n "Enter a variable name you want to know; just ENTER to quit:"
read var
do
case "$ var" in
"" ) break;;
*) Eval echo \ $ $ var;;
esac
done
done
$. / Trace ab cde fg h
Enter a variable name you want to know; just ENTER to quit: dir
.
Enter a variable name you want to know; just ENTER to quit: file
trace
Enter a variable name you want to know; just ENTER to quit: count
A
Enter a variable name you want to know; just ENTER to quit: arg
a
Enter a variable name you want to know; just ENTER to quit: [ENTER]
Enter a variable name you want to know; just ENTER to quit: count
2
Enter a variable name you want to know; just ENTER to quit: arg
b
Enter a variable name you want to know; just ENTER to quit: [ENTER]
Enter a variable name you want to know; just ENTER to quit: count
3
Enter a variable name you want to know; just ENTER to quit: arg
cde
Enter a variable name you want to know; just ENTER to quit: [ENTER]
Enter a variable name you want to know; just ENTER to quit: count
4
Enter a variable name you want to know; just ENTER to quit: arg
fg
Enter a variable name you want to know; just ENTER to quit: [ENTER]
Enter a variable name you want to know; just ENTER to quit: count
5
Enter a variable name you want to know; just ENTER to quit: arg
h
Enter a variable name you want to know; just ENTER to quit: [ENTER]
([ENTER] the ENTER means that you clicked on .)