Saturday, December 29, 2012

Unix Shell Script

exec command &      后台运行且从ps -ef上能看到该command
. command              前台sibling方式运行,如果被另一个ksh以. command方式调用,ps -ef上不能看到该command
command                child方式运行,ps -ef不能看到该command

$ ls -l /dev | grep ’^b’
$ ls [x-z]4*
y4sale z4
$ ls [!a-y]*
z4 zed
$ history
$ r 10 # repeat command number 10
repeat recently issued commands is to press Esc/K over and over
If you only know the first letter or first few letters of a command, you can type
<esc>\ and the KornShell will complete the remaining letters for you. ?
$ var1=”Brown”
$ print "$var1"
commonly used KornShell reserved variables:
dtci-ndadabin01:speng $ echo $PS1
dtci-ndadabin01:${LOGNAME} $
dtci-ndadabin01:speng $ echo $PS2
>
dtci-ndadabin01:speng $ echo $PPID
10356
PWD Present working directory set by the cd command
RANDOM A random integer from 1 to 32767
If you do export var, then shell scripts can access the value of var.
$ export #list environment
To run a program in the background, place an ampersand (&) at the end of the command line
Only one command at a time can run in the foreground; however, multiple
commands can simultaneously run in the background. The background is a good
place to run time-consuming commands.
If you run a pipeline in the background, both processes show up in ps
The following code example shows how to wait for a background process to complete.
$ wait %1
vi Refresher
J Join two lines
p Paste the contents of the paste buffer
4yy Copy this line and the next three lines into the paste buffer
3dd Delete this line and the next two lines; place the deleted lines into the paste buffer

fork() and exec()
The fork() command creates a new process that runs the same program as the
parent (a new nest with the same egg).
The exec() command replaces the program in the process with a new program.
A KornShell script can be executed in either of the following two ways:
! As an argument to ksh
$ ksh myshellscript
To run a shell script as an argument to ksh, the user invoking the shell script must
have read permission on the shell script file.
! By name
To run a shell script by name, simply type its pathname:
$ myshellscript
To run a shell script by name, the user invoking the shell script must have read
and execute permission on the shell script file.

Positional Parameters
Parameter Assignment
$# Total number of positional parameters
$* All positional parameters
$0 The filename of the KornShell script
$1 The first positional parameter
$2 The second positional parameter
$3 The third positional parameter

${10} The tenth positional parameter

Use the shift statement to slide positional parameters.
For example, the following script uses the positional parameters to analyze the
command line arguments passed by the user.
Example
$ cat shifty
print “$1”
shift
print “$1”
shift
print “$1”
$ shifty HELLO THERE
HELLO
THERE

$ cat -n save.ksh
1 while [[ -a $1 ]]
2 do
3 cp $1 $1.save
4 shift
5 done
$ ksh -x sav.ksh abc.dat xyz # run in trace mode
+ [[ -a abc.dat ]]
+ cp abc.dat abc.dat.save
+ shift
+ [[ -a xyz ]]
+ cp xyz xyz.save
+ shift
+ [[ -a ]]

Provide a default value for a parameter to be used if the parameter is not set, as
shown below.
$ cat myscript
print ${1:-abc}
print ${2:-mouse}

Escape SequenceWhat It Does
" "Turns off the special significance of all enclosed characters except $ ` " and \
´ ´Turns off the special significance of all enclosed characters
\Escape the character that comes immediately after the \


 
The KornShell provides four techniques for testing arguments:
1. [[ ]] — new with KornShell (preferred for string tests)
2. (( )) — new with KornShell (preferred for math tests)
3. test command — Bourne shell and KornShell
4. []— Bourne shell & KornShell
All four techniques test arguments and assign the outcome of that test to the
special shell variable $?. The value of $? will be either:
zero SUCCESS
or
nonzero FAILURE
Using the (( )) Command
Sample usage of the (( )) command is shown below.
$ XX=17
$ (( $XX == 17 ))
$ print $?
0
Using the test Command
Sample usage of the test command is shown below.
$ XX=17
$ test $XX -eq 17
$ print $?
0
Using the [ ] Command
Sample usage of the [] command is shown below.
$ XX=17
$ [ $XX -eq 17 ]
$ print $?
0
Note: Spaces around [[ and ]] are required, as shown below.
$ [[“$response” = “Yes” ]]
ksh: [[: not found
 
Integer Comparison Operators
Operator Returns
n1 == n2 Success if integers n1 and n2 are equal
n1 != n2 Success if integers n1 and n2 are not equal
n1 > n2 Success if integer n1 is greater than integer n2
n1 >= n2 Success if integer n1 is greater than or equal to integer n2
n1 < n2 Success if integer n1 is less than integer n2
n1 <= n2 Success if integer n1 is less than or equal to integer n2

String Comparison
Operator Returns
-z s1 Success if length of string s1 is zero
-n s1 Success if length of string s1 is non-zero
s1 = s2 Success if strings s1 and s2 are identical
s1 != s2 Success if strings s1 and s2 are not identical
s1 < s2 Success if string s1 comes before string s2 based on their ASCII values
s1 > s2 Success if string s1 comes after string s2 based on their ASCII values

File Enquiry Operators
Operator Returns
-a file Success if file exists
-r file Success if file exists and is readable
-w file Success if file exists and is writable
-x file Success if file exists and is executable
-f file Success if file exists and is a regular file (as opposed to a directory)
-d file Success if file exists and is a directory
-s file Success if file exists and has a size greater than zero
file1 -nt file2 Success if file1 is newer than file2
file1 -ot file2 Success if file1 is older than file2
file1 -ef file2 Success if file1 is another name for file2

The following logic operators are shown in decreasing order of precedence.
Operator What It Does
! Unary negation operator
&& Logical AND operator
|| Logical OR operator

if [[ -f $1 ]]
then
print "$1 is a plain file"
elif [[ -d $1 ]]
then
print "$1 is a directory file"
else
print "$1 is neither a plain file nor a directory"
fi

while [[ -n $1 ]] # loop until there are no more arguments
do
if [[ -r $1 ]]
then
cp $1 $NEWDIR
fi
shift # get next command line argument
done

while true
do
lines executed in an infinite loop
done
true always returns a 0 (success) value.


The for loop of KornShell is somewhat different than the for loop of most other
languages.
In most other languages, the for loop initializes a variable to a numerical value
and then increments or decrements that value with each iteration of the loop. In the
KornShell, the for loop iterates through a collection of strings or filenames.


# The following for loop creates fa.new, fb.new, fc.new and fd.new:
for FILE in fa fb fc fd
do
cp ${FILE} ${FILE}.new
done

The following is a special case of for that uses positional parameters.
# The following for loop iterates one time for each command
# line argument:
for FILE
do
cp ${FILE} ${FILE}new
done
Note:
for FILE
is equivalent to:
for FILE in $*

Invoking the shell with the -x option provides an execute trace. Invoking the shell
with the -v option provides a verbose trace.

Verbose trace prints shell commands as they are read, and is useful for syntax checking.
An example of using execute trace inside a shell script is shown below.
Example
$ cat save
while [[ -a $1 ]]
do
set -o xtrace # turn on execute trace
cp $1 $1.save
set +o xtrace # turn off execute trace
shift
done
$ save abc.dat xyz
+ cp abc.dat abc.dat.save
+ cp xyz xyz.save

Assign the standard output of command to var, as shown below.
var=$(command)
$ foo=$(ls s*) # assign the output of ls s* to variable foo
$ print $foo
s.cnv.c start superx

Instead of running a KornShell script as a child, you can run it as a sibling.
Although the second script is termed “sibling,” the original script remains the
parent. By running as a sibling, the script can change the parent’s environment.
To run as a sibling, precede the KornShell script with a . (dot) and then a space.

cmd1 && cmd2 execute cmd2 only if cmd1 succeeds.
$ who | grep -q sam && print "sam is logged on"
cmd1 || cmd2 execute cmd2 only if cmd1 fails.
$ who | grep -q sam || print "sam NOT logged on"

其中单引号更严格一些,它可以防止任何变量扩展;而双引号可以防止通配符扩展但允许变量扩展.此外还有一种防止这种扩展的方法,即使用转义字符——反斜杆:\
if [ $# -lt 3 ] ; then 表达式判断输入命令行参数是否小于3 (特殊变量$# 表示包含参数的个数

shell也有一个真正的调试模式,如果脚本"strangescript"出错,可以使用如下命令进行调试:
sh -x strangescript
上述命令会执行该脚本,同时显示所有变量的值。
shell还有一个不执行脚本只检查语法的模式,命令如下:
sh -n your_script
这个命令会返回所有语法错误。


-f1,7  copies  the  first  and seventh field
                only


Programs written for the Bourne
shell can run under the Korn shell without modification.

Get ksh version
dtci-ndadabin01:speng $ what /bin/ksh
/bin/ksh:
   Version M-11/16/88i
   SunOS 5.10 Generic 118872-04 Aug 2006

$ for i in $(ls); do cp $i $i.bak; done
If a command is terminated with a \ character, it is continued on the next line.

If two commands are separated with &&, the second command is
only executed if the first command returns a zero exit status. Here,
the echo command is executed, because ls ran successfully:
$ ls temp && echo "File temp exists"
If two commands are separated with | |, the second command is only
executed if the first command returns a non-zero exit status.

You can implement a simple if command by using the &&
and | | operators together like this:
command1 && command2 | | command3

echo "This is file temp:";cat temp|nl
{ echo "This is file temp:";cat temp; }|nl  #By using {}'s, the output from both commands is line numbered:
There must be whitespace after the opening {, or else you get a syntax
error. One more restriction: commands within the {}'s must be
terminated with a semi-colon when given on one line.

By using the > symbol, the standard output of a command can be redirected to a file, If the file doesn't exist, then it is created. Otherwise, the contents are
usually overwritten.
Standard output can be appended to a file by using the >> redirect operator.
Standard output is closed with the >&– redirect operator:
$ echo "This is going nowhere" >&-
$
The >| operator is used to force overwriting of a file, even if the
noclobber option is enabled. Here, file.out can now be overwritten,
even though the noclobber option is set:
$ ls >| file.out

The
Korn shell automatically assigns file descriptor 0 to standard input for reading, file descriptor 1 to standard output for writing, and file
descriptor 2 to standard error for reading and writing.
$ ls tmp t.out 2>ls.out
There can be no space between the 2 and > symbol, otherwise the 2 is interpreted as an argument to the command.
$ ls tmp t.out 2>ls.out 1>&2
In the command, the standard error and output are sent to ls.out by specifying multiple redirections on the same command line. First,
>&2 causes standard output to be redirected to standard error. Then,2>ls.out causes standard error (which is now standard output and
standard error) to be sent to ls.out:
$ { echo "This is going to stdout" >&1 ; \
> echo "This is going to stderr" >&2 ; } >out 2>&1
$ cat out
This is going to stdout
This is going to stderr

Here documents is a term used for redirecting multiple lines of standard input to a command.
cat >> profile <<END
> export 1
> export 2
> END

The ! character can be used with [ ] to reverse the match. In other
words, [!a] matches any character, except a.
$ ls [!d]*

This pattern matches anti, antic, antigen, and antique:
$ match anti*(c|gen|que)
+(pattern)   This format matches one or more occurrences of pattern.
@(pattern)  This format matches exactly one occurrence of pattern.
!(pattern)   This format matches anything except pattern.

File name substitution can be disabled by setting the noglob option using the set command:
$ set —o noglob
or
$ set —f

The format for command substitution is:
$(command)
$ echo The date is $(date)
The date is Fri Jul 27 10:41:21 PST 1996

For compatibility with the Bourne shell, the following format for command substitution can also be used:
`command `

$((arithmetic-expression))
$ echo $((8192*16384%23))

The Korn shell supports four data types: string, integer, float, and
array. If a data type is not explicitly defined, the Korn shell will
assume that the variable is a string.
By default, all variables are global in scope. However, it is possible to
declare a local variable within a function.

To assign a value and/or
attribute to a Korn shell variable, use the following format with the
typeset command:
typeset –attribute variable=value
or
typeset –attribute variable
typeset +attribute variable
remove attribute from variable
typeset —r ...       Once the readonly attribute is set, a variable cannot be assigned another value.
typeset —i NUM=1  The integer attribute (–i) is used to explicitly declare integer variables.
typeset —E5 X=123.456   $ print $X  123.46 The float command can also be used to declare a float variable, but does not allow for specifying the precision.

Multiple attributes can also be assigned to variables. This command sets the integer and autoexport attributes for TMOUT:
$ typeset —ix TMOUT=3000
list all the integer type variables and their values:
$ typeset -i
Variables can be assigned command output using this format:
variable=$(command)
or
variable=`command`

? exit status of the last command
$ process id of the current Korn shell
-– current options in effect
! process id of the last background command or co-process
ERRNO error number returned by most recently failed system call (system dependent)
PPID process id of the parent shell

${#variable}   This is expanded to the length of variable.
$ print ${X:-cde}  After X is unset, the alternate value cde is used:
$ X=A
$ X[1]=B
The original assignment to variable X is not lost. The first array element (X[0]) is still assigned A.
$ set —A DAY Mon Tue Wed Thu Fri Sat Sun
print ${DAY[3]} ${DAY[5]}
print ${DAY[*]}  or print ${DAY[@]}
print ${#DAY[*]}
To get values for a subset of an array, use this format:
${variable[*]:start_subscript:num_elements}
or
${variable[@]:start_subscript}
$typeset —u DAY
print ${DAY[*]}

Double quotes are like single quotes, except that they do not remove
the meaning of the special characters $, `, and \.
fc —l —5

Jobs running in the foreground are suspended by typing Ctl-z (Controlz)
and backgrounded jobs are brought back into the foreground with the fg command.  $ fg %3
The status and other information about all jobs is displayed using the jobs command.
The + indicates the current job,and – indicates the previous job:
$ jobs
[3] + Stopped split —5000 hugefile
[2] — Running find / —name core —print &
[1] Running sleep 25 &
The jobs -l command shows the same information, along with the
process ids, while jobs –-p only gives you the process ids.
$ sleep 100 &
[1] 254
$ kill %1
It could also be given as kill 254.
You can make the Korn shell wait for some or all background jobs to complete with the wait command. If no argument is given, the Korn
shell waits for all background jobs to complete.
Jobs being executed in the background are prevented from generating output by setting stty tostop. The only way to see the output is to bring the job back into the foreground.
The nohup command can also be used to direct output from
background jobs. It causes standard output and standard error to be
automatically sent to nohup.out, or whatever file you give it.
The nohup command will keep jobs running, even if you log out.
The Korn shell displays a warning message if you try to exit from the shell while jobs are stopped.

Integer arithmetic can be done with the let command and arithmetic expressions.
$ let "X=1 + 1"
The ((...)) command is equivalent to the let command, except that all characters between the (( and )) are treated as quoted arithmetic
expressions.
variables can be explicitly declared integer type by using the typeset –i command.
$typeset —i DAYS MONTHS=12

The [[...]] command is used to evaluate conditional expressions with file attributes, strings, integers, and more.
If you are familiar with the test and [...] commands, then you'll recognize that [[...]] is just a new and improved version of the same
commands. It basically functions the same way, except that a number of new operators are available.
$ X=abc
$ [[ $X = abc ]] && print "X is set to abc"
X is set to abc

This expression evaluates to true if there are less than or equal to three positional parameters set:
[[ $# —le 3 ]] && print "3 or less args given"

The ! operator negates the result of any [[...]] expression when used like this:
[[ ! expression ]]
For example, to check if X is not equal to abc:
$ X=xyz
$ [[ ! $X = abc ]] && print "$X not equals abc"
xyz not equals abc

$ print "This is output again" | read LINE
$ print $LINE
This is output again

$ cat kcat
IFS=:
exec 0<$1
while read LINE
do
print $LINE
done

The . command reads in a complete file, then executes the commands
in it as if they were typed in at the prompt. This is done in the current
shell, so any variable, alias, or function settings stay in effect. It is
typically used to read in and execute a profile, environment, alias, or
functions file.

Co-processes are commands that are terminated with a |& character.
They are executed in the background, but have their standard input
and output attached to the current shell. The print –p command is
used to write to the standard input of a co-process, while read –p is
used to read from the standard output of a co-process.

n<&p redirect input from co-process to file
descriptor n. If n is not specified, use
standard input.
n>&p redirect output of co-process to file
descriptor n. If n is not specified, use
standard output.
print –p write to the standard input of a coprocess
read –p read from the standard output of a coprocess

The times command displays the amount of time the current Korn
shell and child processes. The first line shows the total user and
system time (in hundredths of a second) for the current Korn shell,
while the second line shows the totals for the child processes.

The true command does one thing: return a zero exit status.

dtci-ndadabin01:speng $ let "X=$SECONDS*60"
dtci-ndadabin01:speng $ print $X
5360100

No comments:

Post a Comment