UNIX SHELL编程.docx

上传人:b****6 文档编号:8451826 上传时间:2023-01-31 格式:DOCX 页数:20 大小:23.95KB
下载 相关 举报
UNIX SHELL编程.docx_第1页
第1页 / 共20页
UNIX SHELL编程.docx_第2页
第2页 / 共20页
UNIX SHELL编程.docx_第3页
第3页 / 共20页
UNIX SHELL编程.docx_第4页
第4页 / 共20页
UNIX SHELL编程.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

UNIX SHELL编程.docx

《UNIX SHELL编程.docx》由会员分享,可在线阅读,更多相关《UNIX SHELL编程.docx(20页珍藏版)》请在冰豆网上搜索。

UNIX SHELL编程.docx

UNIXSHELL编程

ShellScript编程

□前言

在DOS中,你可能会从事一些例行的重覆性工作,此时你会将这些重覆性的命令写成批次档,只要执行这个批次档就等於执行这些命令。

大家会问在UNIX中是否有批次处理这个东东,答案是有的。

在UNIX中不只有如DOS的批次处理,它的功能比起DOS更强大,相对地也较复杂,已经和一般的高阶语言不相上下。

在UNIX中大家都不叫做批次档,而叫做ShellScript。

一般而言,ShellScript的地位和其它的可执行档(或命令)是完全相同的,只不

过ShellScript是以文字档的方式储存,而非二进位档。

而执行ShellScript时,必须

有一个程式将其内容转成一道道的命令执行,而这个程式其实就是Shell,这也就是为

什麽我们叫做ShellScript的原因(往後我们称为Script)。

不同Shell的Script基本

上会有一些差异,所以我们不能将写给Ashell的Script用Bshell执行。

而在UNIX中

大家最常使用BourneShell以及CShell,所以这堂课就介绍这两种Script的写法。

□将文字档设为可执行的ShellScript

如果我们已经写好Script,如何将其设成可执行档呢?

因为Script其实是一个可执行档,所以必须将其存取权设定成可执行。

我们可以使用下列命令更改存取权:

chmodu+xfilename只有自己可以执行,其它人不能执行

chmodug+xfilename只有自己以及同一群可以执行,其它人不能执行

chmod+xfilename所有人都可以执行

而我们如何指定使用那一个Shell来解释所写的Script呢?

几种基本的指定方式如

下所述:

1.如果Script的第一个非空白字元不是"#",则它会使用BourneShell。

2.如果Script的第一个非空白字元是"#"时,但不以"#!

"开头时,则它会使用CShell。

3.如果Script以"#!

"开头,则"#!

"後面所写的就是所使用的Shell,而且要将整个路径名称指出来。

这里建议使用第三种方式指定Shell,以确保所执行的就是所要的。

BourneShell的路

径名称为/bin/sh,而CShell则为/bin/csh。

1.使用BourneShell

┌——————————┐┌——————————┐

│echoenterfilename││#!

/bin/sh│

│.│or│.│

│.││.│

│.││.│

└——————————┘└——————————┘

2.使用CShell

┌——————————┐┌——————————┐

│#CShellScript││#!

/bin/csh│

│.││.│

│.││.│

│.││.│

└——————————┘└——————————┘

3.使用/etc/perl

┌——————————┐

│#!

/etc/perl│

│.│

│.│

│.│

└——————————┘

除了在Script内指定所使用的Shell外,你也可以在命令列中强制指定。

比如你要

用CShell执行某个Script,你可以下这个命令:

cshfilename

此时的Script的存取权就不一定要为可执行档,其内部所指定的Shell也会无效,详细

的情形後面会讨论。

□Script的基本结构及观念

Script是以行为单位,我们所写的Script会被分解成一行一行来执行。

而每一行可

以是命令、注解、或是流程控制指令等。

如果某一行尚未完成,可以在行末加上"\",

这个时候下一行的内容就会接到这一行的後面,成为同一行,如下

┌———————————┐

│echoThemessageis\│

│toolongsowehave\│

│tosplititinto\│

│severallines│

└———————————┘

当Script中出现"#"时,再它後面的同一行文字即为注解,Shell不会对其翻译。

在Script中要执行一个命令的方法和在命令列中一样,你可以前景或背景执行,执行命令时也会需要设定一些环境变数。

Script的流程控制和一般高阶语言的流程控制没有什麽两样,也和高阶语言一样有副程式。

这些使得Script的功能更加强大。

为了达到与高阶语言相同的效果,我们也可以在Script中设定变数,如此使Script成为一个名付其实的高阶语言。

□BourneShell

一、变数

BourneShell的变数型态只有字串变数,所以要使用数值运算则必须靠外部命令达成目的。

而其变数种类有下列几种:

1.使用者变数

这是最常使用的变数,我们可以任何不包含空白字元的字串来当做变数名称。

设定变数值时则用下列方式:

var=string

取用变数时则在变数名称前加上一"$"号。

┌———————┐

│name=Tom│

│echoname│

│echo$name│

└———————┘

结果如下:

name

Tom

2.系统变数(环境变数)

和使用者变数相似,只不过此种变数会将其值传给其所执行的命令。

要将一使用者变数设定为系统变数,只要加上:

exportvar

┌———————┐

│name=Tom│

│exportname│

└———————┘

以下是使用者一进入系统之後就已设定好的系统变数:

$HOME使用者自己的目录

$PATH执行命令时所搜寻的目录

$TZ时区

$MAILCHECK每隔多少秒检查是否有新的信件

$PS1在命令列时的提示号

$PS2当命令尚未打完时,Shell要求再输入时的提示号

$MANPATHman指令的搜寻路径

3.唯读的使用者变数

和使用者变数相似,只不过这些变数不能被改变。

要将使用者变数设成唯读的

,只要加上:

readonlyvar

而若只打readonly则会列出所有唯读的变数。

还有一点,系统变数不可以设定

成唯读的。

┌———————┐

│name=Tom│

│readonlyname│

│echo$name│

│name=John│

│readonly│

└———————┘

结果如下:

Tom

name:

isreadonly

readonlyname

readonly......

4.特殊变数

有些变数是一开始执行Script时就会设定,并且不以加以修改,但我们不叫它唯读的系统变数,而叫它特殊变数(有些书会叫它唯读的系统变数),因为这些变数是一执行程式时就有了,况且使用者无法将一般的系统变数设定成唯读的。

以下是一些等殊变数:

名称

意义

$0

这个程式的执行名字

$n

这个程式的第n个参数值,n=1..9

$*

这个程式的所有参数

$#

这个程式的参数个数

$$

这个程式的PID

$!

执行上一个背景指令的PID

$?

执行上一个指令的返回值

当你执行这个程式时的参数数目超过9个时,我们可以使用shift命令将参数往前移一格,如此即可使用第10个以後的参数。

除此之外,吾人可以用set命令改变$n及$*,方法如下:

setstring

如此$*的值即为string,而分解後则会放入$n。

如果set命令後面没有参数,

则会列出所有已经设定的变数以及其值。

档名:

ex1参数:

thisisatest

┌———————————┐

│echoFilename:

$0│

│echoArguments:

$*│

│echoNo.ofargs.:

$#│

│echo2ndarg.:

$2│

│shift│

│echoNo.ofargs.:

$#│

│echo2ndarg.:

$2│

│sethello,everyone│

│echoArguments:

$*│

│echo2ndarg.:

$2│

└———————————┘

结果如下:

Filename:

ex1

Arguments:

thisisatest

No.ofargs.:

4

2ndarg.:

is

No.ofargs.:

3

2ndarg.:

a

Arguments:

hello,everyone

2ndarg.:

everyone

值得一提的是,当你想从键盘输入一变数值时,你可以使用下面的命令:

readvar1var2.....

这时read会将一个字分给一个变数。

如果输入的字比变数还多,最後一个变数会将

剩下的字当成其值。

如果输入的字比变数还少,则後面的变数会设成空字串。

如果需要处理数值运算,我们可以使用expr命令。

其参数及输出列於附录A。

二、执行命令

在BourneShell中有五种方法执行一个命令,而这五种方式所产生的果有些许的不

同。

1.直接下命令

这个方式和在命令列中直接下命令的效果一样。

2.使用sh命令

shcommand

这个档案必须是BourneShell的Script,但这个档案并不一定要设成可执行。

除此之外和直接下命令的方式一样。

3.使用"."命令

.command

这时和使用sh命令相似,只不过它不像sh一般会产生新的process,相反地,

它会在原有的process下完成工作。

4.使用exec命令

execcommand

此时这个Script将会被所执行的命令所取代。

当这个命令执行完毕之後,这个

Script也会随之结束。

5.使用命令替换

这是一个相当有用的方法。

如果想要使某个命令的输出成为另一个命令的参数

时,就一定要使用这个方法。

我们将命令列於两个"`"号之间,而Shell会以

这个命令执行後的输出结果代替这个命令以及两个"`"符号。

str='Currentdirectoryis'`pwd`

echo$str

结果如下:

Currentdirectoryis/users/cc/mgtsai

这个意思是pwd这个命令输出"/users/cc/mgtsai",而後整个字串代替原

来的`pwd`设定str变数,所以str变数的内容则会有pwd命令的输出。

number=`expr$number+1`

这就是先前所提要作数值运算的方法,基本上expr命令只将运算式解,而

後输出到标准输出上。

如果要将某变数设定成其值,非得靠命令替换的方

式不可。

这个例子是将number变数的值加1後再存回number变数。

三、流程控制

在介绍流程控制之前,我们先来看看test命令。

test命令的参数是条件判断式,当

条件为真时则传回非零值,而条件为伪时则传回零。

在所有的流程控制都必须用到

test命令来判断真伪。

而test命令的使用方法则列於附录B。

test$#=0

如果执行这个程式没有参数时,会传回非零值代表"$#=0"这个条件成立。

之则会传回零。

以下介绍各种流程控制:

1.ifthen

语法以及流程图如下

语法以及流程图如下

│FALSE

if(condition)<condition>—┐

then│TRUE│then-commandsthen-commands│

fi├————┘

condition是一个test命令。

往後所介绍的各种流程中的condition都是test

命令。

档名:

chkarg

┌———————————┐

│if(test$#!

=0)│

│then│

│echoArg1:

$1│

│fi│

└———————————┘

$chkargHello

Arg1:

Hello

$chkarg

$

2.ifthenelse

语法以及流程图如下

│FALSE

if(condition)<condition>—————┐

then│TRUE│

then-commandsthen-commandselse-commands

else├————————┘

else-commands│

fi

3.ifthenelif

语法以及流程图如下

│FALSE

if(condition1)<condition1>—┐

then│TRUE│FALSE

commands1commands1<condition2>—┐

elif(condition2)││TRUE│

then│commands2commands3

commands2├—————┴————┘

else│

commands3

commands3

fi

echo'word1:

\c'

readword1

echo'word2:

\c'

readword2

echo'word3:

\c'

readword3

if(test"$word1"="$word2"-a"$word2"="$word3")

then

echo'Match:

words1,2,&3'

elif(test"$word1"="$word2")

then

echo'Match:

words1&2'

elif(test"$word1"="$word3")

then

echo'Match:

words1&3'

elif(test"$word2"="$word3")

then

echo'Match:

words2&3'

else

echo'Nomatch'

fi

4.forin

语法以及流程图如下

│FALSE

forvarinarg-list┌—<arg-list还有东西吗?

>—┐

do││TRUE│

commands│从arg-list取得一项│

done│放到变数var│

│││

│commands│

└——————┘│

┌———————————┐┌———————┘

│forainxxyyzz││

│do│

│echo$a│

│done│

└———————————┘

结果如下:

xx

yy

zz

5.for

语法以及流程图如下

│FALSE

forvar┌—<参数中还有东西吗?

>—┐

do││TRUE│

commands│从参数中取得一项│

done│放到变数var│

│││

│commands│

└—————┘│

档名:

lstarg┌———————┘

┌———————————┐│

│fora│

│do│

│echo$a│

│done│

└———————————┘

$lstargxxyyzz

xx

yy

yy

zz

6.while

语法以及流程图如下

│FALSE

while(condition)┌—<condition>—┐

do││TRUE│

commands│commands│

done└————┘│

┌————┘

┌———————————————┐

│number=0│

│while(test$number-lt10)│

│do│

│echo"$number\c"│

│number=`expr$number+1`│

│done│

│echo│

└———————————————┘

结果如下:

0123456789

7.until

语法以及流程图如下

│TRUE

until(condition)┌—<condition>—┐

do││FALSE│

commands│commands│

done└————┘│

┌————┘

它和while的不同只在於while是在条件为真时执行回圈,而until是在条件

为假时执行回圈。

8.break及continue

这两者是用於for,while,until等回圈控制下。

break会跳至done後方执行

,而continue会跳至done执行,继续执行回圈。

9.case

语法以及流程图如下

│TRUE

casestrin<str=pat1>————commands1—┐

pat1)commands1;;│FALSETRUE│

pat2)commands2;;<str=pat2>————commands2—┤

pat3)commands3;;│FALSETRUE│

esac<str=pat3>————commands3—┤

│FALSE│

├————————————┘

而pat除了可以指定一些确定的字串,也可以指定字串的集合,如下

*任意字串

?

任意字元

[abc]a,b,或c三字元其中之一

[a-n]从a到n的任一字元

|多重选择

┌———————————————┐

│echo'EnterA,B,orC:

\c'│

│readletter│

│case$letterin│

│A|a)echo'YouenteredA.';;│

│B|b)echo'YouenteredB.';;│

│C|c)echo'YouenteredC.';;│

│*)echo'NotA,B,orC';;│

│esac│

└———————————————┘

10.函数

格式如下

function-name()

{

commands

}

而要呼叫此函数,就像在命令列下直接下命令一般。

□CShell

CShell有些特性和BourneShell一样,但有些不相同。

这里介绍与BourneShell

不相同的地方。

一、变数

1.字串变数

这个部分和BourneShell的变数一样,只不过在设定变数值时不能使用Bourne

Shell的方式,而必须打:

setvar=value

2.数字运算

基本上CShell没有数字变数,但CShell却有简单的方法处理数字运算:

@varoperatorexpression

operator可以是C语言中的=,+=,-=,......,而expression则是运算式。

算式的运算子如下:

A.()改变计算的顺序

~@

B.~位元NOT运算

@~

!

逻辑否定

C.%取馀数

/除*乘-减+加

D.>>右移

<<左移

E.>大於

<小於>=大於等於

<=小於等於!

=不等於

==等於

F.&位元AND运算

^位元XOR运算|位元OR运算

G.&&逻辑AND

||逻辑OR

除此之外,我们也可以检验一个档案的状态,如下

-nfilename

而-n可为下列之一

-d档案是一个目录档案

-e档案存在

-f档案为一般的档案

-o使用者拥有这个档案

-r使用者可以读取这个档案

-w使用者可以写入这个档案

-x使用者可以执行这个档案

-z档案长度为0

@count=count+1

@flag=-e/users/cc/mgtsai/mail&&-e/usr/spool/mail

3.阵列

在CShell中,我们可以宣告阵列变数,方式如下

setvar=(val1val2......)

而var[1]之值为val1,var[2]之值为val2......。

而$var代表整个阵列。

我们

可以用$#var来计算阵列个数,也可以用$?

var来检查某个变数是否已宣告。

4.特殊变数

$argv和BourneShell的$*相似,只不过这是一个阵列。

$argv[n]和BourneShell的$n相同,但不受个数限制。

$#argv和BourneShell的$#相同

$home和BourneShell的$HOME相同

$path和BourneShell的$PATH相似,只不过这是一个阵列

$prompt和BourneShell的$PS1相同

$shellShell的路径名称

$status和BourneShell的$?

相同

$$和BourneShell的$$相同

$<键盘输入

二、执行命令

基本上和BourneShell相同,只有一点在BourneShell中的"."命令在CShell中

则为"source"命令。

三、流程控制

在CShell中流程控制不像BourneShell中一般需要使用test命令。

相反地,它和

C语言类似只要在条件中写出运□式即可。

当运算结果不为零时,其值为真,为零

时其值为伪。

以下是CShell的流程控制

1.if

语法如下

if(expression)simple-command

2.goto

语法如下

gotolabel

这时程式会跳至以l"label:

"开头的那一行执行

if($#argv==2)gotogoodargs

echo'Pleaseusetwoarguments.'

exit

goodrags:

...

3.

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 文学研究

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1