加入收藏 | 设为首页 | 会员中心 | 我要投稿 92站长网 (https://www.92zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

Unix系列shell程序编写

发布时间:2022-10-13 03:30:57 所属栏目:Unix 来源:未知
导读: $$ 当前shell的进程号
$! 上一个子进程的进程号
$@ 所有的参数,每个都用双括号括起
$* 所有参数,用双括号括起
$n 位置参数值,n表示位置
$0 当前shell名
*>产生文件名的特殊字符
包括"*"

$$ 当前shell的进程号

$! 上一个子进程的进程号

$@ 所有的参数,每个都用双括号括起

$* 所有参数,用双括号括起

$n 位置参数值,n表示位置

$0 当前shell名

*>产生文件名的特殊字符

包括"*","?","[]",上面讲过,不再多说。

*>数据或程序控制使用的特殊字符

>(file) 输出重定向到文件中(没有文件则创建,有则覆盖)

>>(file) 输出重定向到文件中(没有则创建,有则追加到文件尾部)

对于引用或逃逸的特殊字符

Bsh用单引号' '和双引号" "将特殊字符或由空白分隔的字引用起来组成一个简单的数据串.使用单引号和双引号的区别是双引号中的内容可进行参数和变量替换.逃逸字符也一样.

$echo "$HOME $PATH"

结果显示$/u/ice_walk/bin:/etc:/usr/bin

而$echo '$HOME $PATH' 结果显示$HOME $PATH

shell的逃逸符是一个"",表示其后的字符不具有特殊的含义或不是shell的函数

$echo $HOME $PATH

结果显$$HOME /bin:/etc:/usr/bin:

3>Bsh的变量

前面我们在多个地方引用了变量,当Shell遇到一个"$"符时(没有被引用或逃逸),它将认为其后为一变量。不论该变量是环境变量还是用户自定义的变量,在命令行中变量名要被变量值替换。例如命令:ls $HOME将列出变量HOME对应目录下的文件。 用户可以在命令行中的任何地方进行变量替换。包括命令名本身,例如:

$dir=ls

$$dir f*

将列出以f开头的文件。

现在详细的介绍下Bsh的变量。Bsh中有四类变量:用户定义的变量、位置变量(shell参数)、预定义变量及环境变量。

用户定义的变量:

用户定义的变量由字母和下划线组成,并且变量名的第一个字符不能为数字(0~9)。与其他UNIX名字一样,变量名是大小写敏感的。用户可以在命令行上用"="给变量赋值,例如:

$NAME=ice_walk

给变量NAME赋值为ice_walk,在应用变量NAME的时候,在NAME前加"$"即可,前面已说,不再废话(别说我废话多,关键是没当过老师:()。可以用变量和其他字符组成新的字,例如:

$SUN=sun

$echo ${SUN}day

在应用shell变量时候,可以在变量名字两边$后面加上{},以更加清楚的显示给shell,哪个是真正的变量,以实现字符串的合并等功能。

结果显示:sunday(注意不能echo $SUNday,因为SUNday变量没定义,读者试下执行结果) 用户也可以在命令行上同时对多个变量赋值,赋值语句之间用空格分开:

$X=x Y=y

注意变量赋值是从右到左进行的

$X=$Y Y=y

X的值是y

$X=z Y=$Z

Y的值是空(变量未赋值时,shell不报错,而是赋值为空)

用户可以使用"unset "命令清除给变量赋的值

用户使用变量时要在其前面加一"$"符,使变量名被变量值所替换。Bsh可以进行变量的条件替换,即只有某种条件发生时才进行替换。替换条件放在一对大括号{}中,如:

${variable: -value} variable是一变量值,value是变量替换使用的默认值

$echo Hello $UNAME

结果显示:Hello

$echo Hello ${UNAME: -there}

结果显示:Hello there

$echo $UNAME

结果显示: (空)

$UNAME=John

$echo Hello ${UNAME: -there}

结果显示:Hello John

可以看出,变量替换时将使用命令行中定义的默认值unix脚本,但变量的值并没有因此而改变。另外一种替换的方法是不但使用默认值进行替换,而且将默认值赋给该变量。其形式如下:

${variable:=value}

该形式在变量替换后同时把值value符给变量variable。

$echo Hello $UNAME

结果显示:Hello

$echo Hello ${UNAME:=there}

结果显示:Hello there

$echo $UNAME

结果显示:there

$UNAME=John

$echo Hello ${UNAME:-there}

结果显示:Hello John

变量替换的值也可以是` `括起来的命令:

$USERDIR={$Mydir: -`pwd`}

第三种变量的替换方法是只有当变量已赋值时才用指定值替换形式:

${variable: +value}

只有变量variable已赋值时,其值才用value替换,否则不进行任何替换,例如:

$ERROPT=A

$echo ${ERROPT: +"Error tracking is acitive"}

结果显示:Error tracking is acitive

$ERROPT=

$echo ${ERROPT: +"Error tracking is acitive"}

结果显示: (空)

我们还可以使用错误检查的条件进行变量替换:

${variable:?message}

当变量variable已设置时,正常替换。否则消息message将送到标准错误输出(若此替换出现在shell程序中,那么该程序将终止)。例如:

$UNAME=

$echo $ {UNAME:?"UNAME HAS NOT BEEN SET"}

结果显示:UNAME HAS NOT BEEN SET

$UNAME=Stephanie

$echo $ {UNAME:?"UNAME HAS NOT BEEN SET"}

结果显示:Stephanie

当没有指定message时,shell将显示一条默认的消息,例如:

$UNAME=

$echo $ {UNAME:?}

结果显示:sh:UNAME:parameter null or not set

4>位置变量或Shell参数

在shell解释用户的命令时,将把命令行的第一个字作为命令,而其他的字作为参数。当命令对应的可执行文件为Shell程序时,这些参数将作为位置变量传送给该程序。第一个参数记为$1,第二个为$2....第九个为$9。其中1到9是真正的参数名,"$"符只是用来标识变量的替换。

位置变量$0指命令对应的可执行文件名。在后面将详细介绍位置变量。

1.只读变量

用户将变量赋值后,为了防止以后对该变量的修改,可以用以下命令将该变量设置为只读变量:

readonly variable

2.export命令

shell执行一个程序时,首先为该程序建立一个新的执行环境,称为子shell。在Bourne Shell中变量都是局部的,即他们只在创建他们的Shell中有意义。用户可以用export命令让变量被其他子Shell识别。但某用户的变量是没法让其他用户使用的。

当用户启动一个新shell时,该shell将使用默认的提示符。因为赋给变量PS1的值只在当前shell中有效。为了让子Shell使用当前Shell中定义的提示符号,可以使用export命令:

$PS1="Enter command:"

Enter command:export PS1

Enter command:sh

Enter command:

此时变量PS1变成了全局变量。它可以被其子Shell使用。当变量被设置成全局的以后,将一直保持有效直到用户退出该变量所在的Shell。用户可以在文件.profile中给一个变量永久赋值。详见"规范Shell"。

基本语句

从本节起,我们将详细介绍Shell程序设计的基本知识,通过编写Shell脚本,用户可以根据自己的需要有条件的或者重复的执行命令。通过Shell程序,可以把单个的UNIX命令组合成一个完全实用的工具,完成用户的任务。

1>什么是Shell程序

当用户在UNIX Shell中输入了一条复杂的命令,如:

$ls -R /|greo myname |pg

我们可以称用户在对Shell编程,当把这条语句写在一个文件里,并且符给该文件可执行权限,那么该文件就是我们传统上说的Shell程序。

2>简单的Shell程序

假设用户每天使用下述命令备份自己的数据文件:

$cd /usr/icewalk;ls * |cpio -o > /dev/fd0

我们可以把它写在一个文件,如:ba.sh中:

$cat >ba.sh

cd /usr/icewalk

ls * |cpio -o > /dev/fd0

^D (ctrl_d)

程序ba.sh就是Shell脚本,用户可以用vi或其他编辑工具编写更复杂的脚本。

此时用户备份文件只需要执行Shell程序ba.sh,执行时需在当前Shell中创建一个子Shell:

$sh ba.sh

程序sh与用户登陆时执行的Bourne Shell相同,但当Sh命令带参数ba.sh后,它将不再是一个交互式的Shell,而是直接从文件ba.sh中读取命令。

执行ba.sh中命令的另一方法是给文件ba.sh执行权限:

$chmod +x ba.sh

此时,用户可以输入文件名ba.sh做为一个命令来备份自己的数据,需要注意的是,用这种方法执行命令的时候,文件ba.sh必须存在于环境变量$PATH所指定的路径上。

Unix系列shell程序编写(中)

3>在Shell中使用数据变量

用户可以在Shell中使用数据变量,例如ba.sh程序:

cd/usr/icewalk

ls|cpio -o > /dev/fd0

该程序中要备份的目录为一常量,即该程序只能用来备份一个目录。若在该程序中使用变量,则会使其更通用:

workdir=$1

cd $workdir

ls * |cpio -o > /dev/fd0

通过这一改变,用户可以使用程序备份变量$workdir指定的目录。例如我们要备份/home/www的内容,只要运行ba.sh /home/www即可实现。(若不明白 $1,下面将详细介绍shell参数的传递,$1代表本sh程序-ba.sh的第一个参数)

4>在Shell程序中加上注释

为了增加程序的可读性,我们提倡加入注释。在Shell程序中注释将以"#"号开始。当Shell解释到"#"时,会认为从"#"号起一直到该行行尾为注释。

5>对Shell变量进行算术运算

高级语言中变量是具有类型的,即变量将被限制为某一数据类型,如整数或字符类型。Shell变量通常按字符进行存储,为了对Shell变量进行算术运算,必须使用expr命令。

expr命令将把一个算术表达式作为参数,通常形式如下:

expr [数字] [操作符] [数字]

由于Shell是按字符形式存储变量的,所以用户必须保证参加算术运算的操作数必须为数值。下面是有效的算术操作符:

+两个整数相加

-第一个数减去第二个数

*两整数相乘

/第一个整数除以第二个整数

%两整数相除,取余数

例如:

$expr 2 + 1

结果显示:3

$expr 5 - 3

结果显示:2若expr的一个参数是变量,那么在表达式计算之前用变量值替换变量名。

$int=3

$expr $int + 4

结果显示:7

用户不能单纯使用"*"做乘法,若输入:

$expr 4*5

系统将会报错,因为Shell看到"*"将会首先进行文件名替换。正确形式为:

$expr 4 * 5

结果显示:20

多个算术表达式可以组合在一起,例如:

$expr 5 + 7 / 3

结果显示:7

运算次序是先乘除后加减,若要改变运算次序,必须使用"`"号,如:

$int=`expr 5 + 7`

$expr $int/3

结果显示:4

或者:

$expr `expr 5+7`/3

结果显示:4

6>向Shell程序传递参数

一个程序可以使用两种方法获得输入数据。一是执行时使用参数。另一种方法是交互式地获得数据。vi编辑程序可以通过交互式的方法获得数据,而ls和expr则从参数中取得数据。以上两种方法Shell程序都可以使用。在"交互式读入数据"一节中将介绍Shell程序通过交互式的方法获得参数。

通过命令行给Shell程序传递参数可以扩大程序的用途。以前面提到的ba.sh程序为例:

$cat >re.sh

cd $workdir

cpio -i < /dev/fd0

^d

程序re.sh恢复了ba.sh程序备份的所有文件。若只从软盘上恢复一个指定的文件,可以用该文件名作为参数,传递给Shell程序re.sh:

程序改写如下:

$cat >re2.sh

cd $workdir

cpio -i $1 < /dev/fd0

^d

用户可以指定要恢复的文件,例如fname

$re2.sh fname

此时文件fname作为第一个位置参数传递给re2.sh,re2.sh的缺点是要恢复两个或多个文件要重复运行,我们可以用$*变量传递不确定的参数给程序:

$cat >re3.sh

cd $workdir

cpio -i $* < /dev/fd0

^d

我们就可以恢复多个文件,例如fname1,fname2,fname3

$re3.sh fname1 fname2 fname3

(以上程序re.sh,re2.sh,re3.sh,假设用户已经chmod了可执行权利)

因为没有赋值的变量可以作为NULL看待,所以若是程序re3.sh在执行时候没赋予参数,那么一个空值将被插入到cpio命令中。该命令将恢复所有保存的文件。

条件判断语句

条件判断语句是程序设计语言中十分重要的语句,该语句的含义是当某一条件满足时,执行指定的一组命令。

1>if - then语句

格式: if command1

then

command2

command3

fi---(if 语句结束)

command4

每个程序或命令执行结束后都有一个返回的状态,用户可以用Shell变量$?获得这一状态。if语句检查前面命令执行的返回状态,若该命令成功执行,那么在then和fi之间的命令都将被执行。在上面的命令序列中,command1和command4总要执行。若command1成功执行,command2和command3也将执行。

请看下面程序:

#unload -program to backup and remove files

cd $1

ls -a | cpio -o > /dev/mnt0

rm *

该程序在备份资料后,删除档案,但当cpio命令不能成功执行时,rm命令还是把资料删除了,我们可不希望这样,为了避免此情况,可以用if - then语句:

#--卸载和判断删除程序

cd $1

if ls -a | cpio > /dev/mnt0

then

rm *

fi

上面程序在cpio执行成功后才删除档案

同时,若执行没有成功,我们希望得到提示,sh中的echo命令可以向用户显示消息,并显示后换行,上面程序可以写成:

#--卸载和判断删除程序

cd $1

if ls -a | cpio > /dev/mnt0

then

echo "正删除文件资料... ..."

rm *

fi

echo命令可以使用一些特殊的逃逸字符进行格式化输出,下面是这些字符及其含义:

Backspace

c显示后不换行

f在终端上屏幕的开始处显示

换行

回车

制表符

v垂直制表符

反斜框

标签: Shell shell shell ll UNIX unix man value 用户创建 交互式读入数据 Unix CD命令 程序 SHELL 执行shell

(编辑:92站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章