Linux入门引导第21章Word格式.docx
《Linux入门引导第21章Word格式.docx》由会员分享,可在线阅读,更多相关《Linux入门引导第21章Word格式.docx(29页珍藏版)》请在冰豆网上搜索。

36helloworld.sh
~/test/bash$chmoda+xhelloworld.sh
-rwxr-xr-x1ghostm55users6304-2208:
~/test/bash$./helloworld.sh
可以看到,在将脚本加上执行权限后,用户就可以直接执行脚本了。
在学习本章的bash编程基础时,这个脚本文件将逐步被拓展,最后成为一个可供学习参考的语法示范脚本。
21.2变量
在使用bash进行脚本编程时,用户可以通过创建变量来动态地存储数据。
变量在许多编程语言中都是必不可少的要素,在shell脚本编程中同样如此。
21.2.1创建一个变量
创建变量的基本语法如下:
变量名=值
等于号(=)是赋值符号,它能够将右边的值赋给变量。
在使用一个变量时,需要注意它是大小写敏感的,变量名不能以数字开头,并且不能同时设置两个相同名称的变量。
现在试着创建一个变量dir:
~/test/bash$dir=/etc
~/test/bash$echo$dir
/etc
~/test/bash$echodir
dir
在命令行下用户就能直接创建变量了。
在对一个命令进行赋值后,如果像要读取变量,那么需要在变量名前加上美元符号($),表示这是一个变量。
如果不加,那么变量名将只是一个普通的字符串罢了。
现在继续创建一个名为whereisdir的变量,简单地在该变量中调用dir变量,显示dir变量的值:
~/test/bash$whereisdir=diris$dir#1
bash:
is:
commandnotfound
~/test/bash$whereisdir="
diris$dir"
#2
~/test/bash$echo$whereisdir
diris/etc
~/test/bash$whereisdir='
diris$dir'
#3
diris$dir
~/test/bash$whereisdir=`echo"
`#4
❑注释1:
在第1次对whereisdir这个变量进行赋值时,值没有加上引号。
于是,bash在解释这条命令时,会将is作为命令看待,由于没有is这个命令,所以bash报了错。
❑注释2:
在第2次对whereisdir这个变量进行赋值时,值加上了双引号。
加上双引号后,它能保留变量值中的空格,如果连续输入多个空格,那么bash会将空格串压缩成单个空格符:
可以看到,在whereisdir变量中包含了已经设定好的变量dir,在显示变量的值时,dir变量得到了拓展,所以显示出的结果时diris/etc。
❑注释3:
在第3次对whereisdir这个变量进行赋值时,值加上了单引号。
可以看到的是,这次的执行结果没有将dir变量拓展开,而是将$dir视为一个字符串显示了出来。
这也正是双引号与单引号在bash中最重要的区别之一。
❑注释4:
在第4次对whereisdir这个变量进行赋值时,值加上的是反单引号。
反单引号在esc键下的一个键位中。
通过反单引号的引用,whereisdir能够保存echo"
这个命令的显示结果。
对于其它命令的调用,同样如此。
事实上,$变量只是${变量}的特殊形式,在遇到如下较为复杂的情况时,后者就变得有用起来:
~/test/bash$country=China
~/test/bash$city=$countryShanghai
~/test/bash$echo$city
用户的本意是想在显示完变量名country后,紧跟字符串Shanghai。
实际情况则是,第一次对city进行赋值时,是将一个名为cityShanghai的变量值赋给了它,由于该变量事先没有赋值,所以显示的是空白行。
如果想要实现用户的本意,那么可以加上花括号,将变量名括起来,实现区分:
~/test/bash$city=${country}Shanghai
ChinaShanghai
这时,变量就能被正确显示了。
在设定变量后,如果想要删除变量,那么可以通过unset命令实现:
~/test/bash$unset$dir
unset:
`/etc'
notavalididentifier
~/test/bash$unsetdir
unset工具后应该直接跟变量名。
如果像示例中一开始那样加上美元符号,那么变量将会被拓展,命令的实际情况是unset/etc,所以会报错。
21.2.2变量的属性
通过bash的内置命令declare或typeset(它们是同一个命令,只是有两个名字),用户可以设定变量的属性。
那么,设置变量的属性有哪些用处呢?
这里先给出一个简单的例子:
~/test/bash$sum=1+1
~/test/bash$echo$sum
1+1
用户在这里时想用变量sum来保存1+1的结果,但是sum变量储存的却是字符串1+1。
这是因为在bash中,变量在默认情况下都是以字符串的形式储存的。
如果想要改变一个变量的类型,就需要使用declare或者typeset。
针对这个示例,我们需要将变量sum设置为整型来达到预先的要求:
~/test/bash$declare-isum=1+1
2
通过命令选项i,declare能够将sum设定为整型变量。
declare还能通过以下命令选项设置变量的属性:
❑-a:
声明一个数组变量
❑-f:
声明一个函数名变量
❑-i:
声明一个整型变量
❑-r:
声明一个只读变量
❑-x:
声明一个全局变量
关于数组变量与函数将会在稍后的小节中讲解,下面讲解什么是只读变量与全局变量。
当用户创建了一个变量后,为了确保变量不会在意外情况下被二次赋值,那么可以通过事先将变量设置为只读属性来得到确保:
~/test/bash$declare-rcity=Shanghai
~/test/bash$echo$city
Shanghai
~/test/bash$city=Beijing
city:
readonlyvariable
在设置了city为只读变量后,如果想要再次对该变量进行赋值,将会得到city是只读变量的错误提示。
并且,一旦变量被设置为了只读,它将无法被去除只读属性或者是删除。
要将一个变量设置为只读属性,还能通过readonly命令实现:
~/test/bash$readonlynum
readonly与带有命令选项r的declare功能相同。
到目前为止,这里所有的变量都是局部变量,只能在当前bash环境中生效:
~/test/bash$cathelloworld.sh
#我的第一个脚本!
echoIcomefrom$Country
~/test/bash$declareCountry=China
~/test/bash$echo$Country
China
~/test/bash$./helloworld.sh
Icomefrom
在脚本helloworld中,我们试着将变量Country的值显示出来,前提是在外部先创建好一个Country变量,并已经对其赋值。
可以看到,虽然在外部能够显示Country这个变量的值,它却无法在脚本中被正确引用。
现在,试着将Country设定为全局变量:
~/test/bash$declare-xCountry
IcomefromChina
~/test/bash$
在将Country设置为全局变量后,脚本中就能显示它的值了。
需要注意的是,全局变量仅对当前bash环境及其子环境有效,而不能对外部环境有效,如果在脚本中设置一个全局变量,那么在执行脚本的环境里这个变量是无效的。
要设置一个全局变量,还能通过命令export实现:
~/test/bash$exportCountry
export与带有命令选项x的declare功能相同。
21.2.3关键字变量
在bash下有着许多默认的关键字变量,这些变量可以通过继承或者是启动时初始化得到,通常它们都是全局变量。
本小节会介绍几个最主要的关键字变量。
PS1
在登录bash后,我们首先可以看到类似这样的命令提示符:
user@localhost:
~$
默认情况下,命令提示符都会由用户名,主机名,当前工作目录以及表示用户身份的提示符号组成。
用户可以自行对命令提示符的显示信息进行定义,bash的命令提示符属性可以在~/.bashrc文件中通过设定变量PS1改变。
这个例子中的PS1变量是:
PS1='
\u@\h:
\w\$'
在设定变量PS1时,\u代表用户名,\h代表主机名,\w代表工作目录的绝对路径,\$显示用户身份的提示符,普通用户登录时该提示符为$,而超级用户则为#。
表21.1给出了最为常用的PS1提示符号:
表21.1主要的PS1提示符号
提示符
含义
\$
只有在以root身份运行时显示为#,否则就是$
\w
工作目录的绝对路径
\W
工作目录名
\d
按照“星期日/月/日期”格式显示的日期
\h
计算机的主机名,不包括域名
\H
计算机的主机名,包括域名
\u
当前用户的用户名
\t
以HH:
MM:
SS的格式,24小时制显示当前时间
\A
MM的格式,24小时制显示当前时间
用户可以随自己的需要自由地设置命令提示符。
HOME
HOME变量在默认情况下是用户的家目录:
~$echo$HOME
/home/user
家目录是用户登录shell后的默认工作目录,HOME变量还能使用波浪符号(~)来指代:
~$echo~
/home/ghostm55
PATH
PATH变量存放着用户查找程序的路径,通常,用户可以直接输入vim来启动编辑器vim,那是因为vim命令存放在PATH变量中包含的目录下:
~$whichvim
/usr/bin/vim
~$echo$PATH
/bin:
/usr/bin:
/sbin:
/usr/sbin:
/opt/kde/bin:
/opt/qt/bin
可以看到,vim命令是在/usr/bin目录下,当查看PATH变量时,可以看到许多以冒号(:
)隔开的路径,其中就包括了/usr/bin。
用户可以在自己的bash配置文件中自行配置PATH变量:
PATH=PATH:
~/bin
这样就能添加/home/user/bin作为搜索路径了。
如果要添加工作目录为搜索路径,那么在任何时候都不要将它放在PATH搜索路径列表的第一位。
这样做会导致不可预测的安全问题。
比如,在工作目录下有个恶意程序ls,这是个使用率极高的命令,一旦先被搜索到执行,那么后果不堪设想。
21.2.4数组变量
bash支持一维数组的变量类型,数组的下标是以0开始的阿拉伯数字,这与C语言中的规则是一样的。
bash中创建一个数组变量的语法如下:
变量名=(值1值2值3...值n)
现在试着创建一个数组变量:
~/test/bash$City=(ShanghaiBeijingGuangZhouChongQing)
~/test/bash$echo$City
~/test/bash$echo${City[0]}
~/test/bash$echo${City[4]}
在这里,City是一个包括4个城市名的数组变量。
当数组变量被赋值后,直接读取变量名将会取得数组中第1个值。
要显示数组中指定的变量,需要将变量名用花括号括起来,并且在中括号中指定显示第几个变量。
❑数组变量中的维数0指代第一个,维数n就是第n+1个变量。
如果所指范围超过已经指定的数组范围,那么将会被视为不存在的变量,从而显示空行。
数组变量同样能够被设置为整形变量:
~/test/bash$nums=(1234a)
~/test/bash$sum=${nums[3]}+${nums[2]}
~/test/bash$echo$sum
4+3
~/test/bash$declare-inums
~/test/bash$declare-isum
7
~/test/bash$echo${nums[4]}
a
可以看到,用户在将数组变量nums的属性改变为整形变量后,数组中的数字就能相加得到结果然后赋值给变量sum,而变量nums[4]的值依然是a。
21.2.5特殊变量
在bash中,有着其指定的特殊变量,它们分别访问一些极为有用的变量值。
$$
变量$$代表着当前程序的PID号:
~/test/bash$echo$$
4127
~/test/bash$ps
PIDTTYTIMECMD
4127pts/200:
00:
00bash
4545pts/200:
00ps
可以看到,特殊变量$$显示出的数字就是当前运行程序进程的PID号。
$?
变量$?
记录的是上一个命令执行后的返回码:
~/test/bash$ddd
ddd:
~/test/bash$echo$?
127
这个示例先试着运行了一个错误指令,然后查看返回码,是127,具体的错误返回码含义要查看相关的资料。
再次查看返回码时,发现数值已经返回到了0,这是因为在上次查看返回码的命令成功返回,值为0。
$#与$n
这里,$n中的n是阿拉伯数字,从$1开始,每个变量都对应着调用脚本的命令参数,而$0代表的是调用脚本的名字:
~/test/bash$echo$0
而特殊变量$#则表示调用脚本的命令参数个数,现在来看一个例子:
$0$1$2"
Thereis$#parametershere"
接着,用户试着执行这个脚本:
~/test/bash$bashparameter.shp1p2p3
parameter.shp1p2
Thereis3parametershere
可以看到,变量$0,$1,$2虽然没有被创建过,但是它们分别代表了调用脚本名、第一个命令参数以及第二个命令参数。
而后面的特殊变量$#则是命令参数的个数
21.2.6学习记录
本小节学习了变量的基本使用,现在,将学习心得写到脚本helloworld中去。
#
#helloworldbashshell学习脚本
############
#变量的学习#
#变量的创建语法为:
变量名=值
Country=China#首先创建一个变量Country
$Country"
#显示China
echo'
$Country'
#显示$Country
#使用${变量}的形式更为标准
Icomefrom${Country}Shanghai"
#变量的删除使用unset
unsetCountry
echo$Country#变量Country已经不存在,显示空行
#整形变量的创建
declare-isum
#只读变量的创建
declare-rsum
#数组变量的创建
#语法:
nums=(1234)#数组的下标从0开始
echo${nums[3]}#数组变量必须用中括号将变量名括起,这里显示结果时4
#特殊变量
echo$0$1$2#分别显示调用脚本名,第一个命令参数,第二个命令参数
echo$##显示命令参数个数
echo$$#显示PID号
在学习shell编程的过程中,写这样一份参考脚本是一个不错的习惯,它能够帮助日后的复习与参考使用。
在完成每一节的学习后,读者都可以自行都会对helloworld进行扩展,以加深对学习过的内容的印象。
21.3控制结构
引入正确的控制结构是编程中最重要的一个环节,bash编程语言也有许多控制结构语句供用户使用,它们分为循环、判断、选择三种。
21.3.1if...elif...else
判断语句if的语法如下:
if条件
then
执行语句
elif条件
then
执行语句
...
else
fi
先看一个例子,有助于对语句的理解:
makeachoice(y/n):
"
readchoice
if["
$choice"
="
y"
]
then
echo"
Yourchoiceisy"
exit0
elif["
n"
Yourchoiceisn"
else
Youshouldhaveasecondthought"
exit1
指令read是等待用户输入一个值赋给指定的变量,在这里,这个变量是NUM。
接下来,程序开始执行判断语句,这里判断语句的思想是:
根据户输入的字符,判断他的输入是y还是n,如果都不是,那么就报错。
在if语句中,子语句elif还有else如果不需要使用,是可以省略的。
如果这里我们只希望判断用户输入的是不是字符y,那么可以将elif与else的子语句块去掉,或者是注释掉:
#elif["
#then
#echo"
#exit0
#else
#exit1
这样,程序就等价于:
test内置命令
在前面if语句的示例中,运用到了内置命令test进行条件判断。
事实上,该句中的中括号是test的简写形式。
test的语法如下:
test表达式
[表达式]
test命令对表达式进行判断,并返回一个值,来表示这个表达式是true(0),还是false
(1)。
test的简写形式是一对中括号,由它将表达式括起来,由于中括号实际上就是一个命令,所以要注意表达式与中括号之间要有空格。
表达式可以是一个,也可以是多个,当有多个表达式时,需要使用布尔操作符对它们进行分割。
-a是布尔与操作符,只有当由-a连接的条件表达式都为真是,整个表达式的值才能为真。
-o时布尔或操作符,只要当由-o连接的条件表达式中有一个为真,那么整个表达式的值就为真。
表达式中的每个元素都必须通过空格来分割。
下面列出的是test的最常用的判别式:
表21.2内置命令test的常用判别式
判别式
-nstring
如果字符串string长度大于0,那么返回值为真
-zstr