Linux入门引导第21章.docx
- 文档编号:7665904
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:29
- 大小:29.90KB
Linux入门引导第21章.docx
《Linux入门引导第21章.docx》由会员分享,可在线阅读,更多相关《Linux入门引导第21章.docx(29页珍藏版)》请在冰豆网上搜索。
Linux入门引导第21章
第21章bash编程入门
bashshell能够作为命令解释器提供给用户与计算机交互的平台,同样能够作为一种编程语言为用户完成各种批处理工作。
bash是所有shell中最适用于shell脚本开发的解释性语言,如果详细展开,其篇幅可能要像这么一本书一样多,本章所展现给读者的,是最常用的shell编程基础与技巧。
21.1创建一个简单的脚本
首先,选择一个合适的编辑器,创建一个脚本文件:
:
~/test/bash$vimhelloworld.sh
这里假设使用vim编辑器来创建,通常来说,脚本文件最好以sh为后缀名命名,接着,输入简单的脚本内容:
#!
/bin/bash
echo"helloworld"#我的第一个脚本!
exit0
现在来分析一下这个简单的脚本中有些什么:
Sha-Bang
bash脚本以一个名为“Sha-Bang”的“#!
”符号开头,后跟bashshell的绝对路径。
它告诉系统调用什么shell环境来解释该脚本。
“Sha-Bang”只能放在脚本文件的第一行。
从第二行开始,任何一行中以井号(#)开头后的字符都属于程序注释,是不会被shell所解释运行的。
echo“hellowolrld”
在这个脚本文件的第二行,有一个echo命令以及一段注释。
bash脚本的注释是从一行中第一个非引用井号开始到行为的部分。
在任何时候,给程序加上一段注释都是没错的。
合理的注释有助于他人或者是自己更好地完成日后的维护工作。
exit0
一个程序结构在结束后,都应当返回一个值,来让调用脚本的程序判断其返回状态,从而更好地处理程序的执行。
在这个脚本中,末尾返回了0表示程序执行成功。
还有一种常见的返回值就是1,它表示程序执行失败。
创建完这样一个简单的脚本后,就可以执行它了:
:
~/test/bash$bashhelloworld.sh
helloworld
:
~/test/bash$
通过命令bash,为脚本创建一个执行环境,使脚本能够运行起来。
同样的,可以将脚本加上执行权限,直接执行脚本:
:
~/test/bash$ls-l
总计4
-rw-r--r--1ghostm55users6304-2208:
36helloworld.sh
:
~/test/bash$chmoda+xhelloworld.sh
:
~/test/bash$ls-l
总计4
-rwxr-xr-x1ghostm55users6304-2208:
36helloworld.sh
:
~/test/bash$./helloworld.sh
helloworld
:
~/test/bash$
可以看到,在将脚本加上执行权限后,用户就可以直接执行脚本了。
在学习本章的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
:
~/test/bash$echo$whereisdir
diris$dir
:
~/test/bash$whereisdir=`echo"diris$dir"`#4
:
~/test/bash$echo$whereisdir
diris/etc
❑注释1:
在第1次对whereisdir这个变量进行赋值时,值没有加上引号。
于是,bash在解释这条命令时,会将is作为命令看待,由于没有is这个命令,所以bash报了错。
❑注释2:
在第2次对whereisdir这个变量进行赋值时,值加上了双引号。
加上双引号后,它能保留变量值中的空格,如果连续输入多个空格,那么bash会将空格串压缩成单个空格符:
:
~/test/bash$whereisdir="diris$dir"
:
~/test/bash$echo$whereisdir
diris/etc
可以看到,在whereisdir变量中包含了已经设定好的变量dir,在显示变量的值时,dir变量得到了拓展,所以显示出的结果时diris/etc。
❑注释3:
在第3次对whereisdir这个变量进行赋值时,值加上了单引号。
可以看到的是,这次的执行结果没有将dir变量拓展开,而是将$dir视为一个字符串显示了出来。
这也正是双引号与单引号在bash中最重要的区别之一。
❑注释4:
在第4次对whereisdir这个变量进行赋值时,值加上的是反单引号。
反单引号在esc键下的一个键位中。
通过反单引号的引用,whereisdir能够保存echo"diris$dir"这个命令的显示结果。
对于其它命令的调用,同样如此。
事实上,$变量只是${变量}的特殊形式,在遇到如下较为复杂的情况时,后者就变得有用起来:
:
~/test/bash$country=China
:
~/test/bash$city=$countryShanghai
:
~/test/bash$echo$city
:
~/test/bash$
用户的本意是想在显示完变量名country后,紧跟字符串Shanghai。
实际情况则是,第一次对city进行赋值时,是将一个名为cityShanghai的变量值赋给了它,由于该变量事先没有赋值,所以显示的是空白行。
如果想要实现用户的本意,那么可以加上花括号,将变量名括起来,实现区分:
:
~/test/bash$city=${country}Shanghai
:
~/test/bash$echo$city
ChinaShanghai
这时,变量就能被正确显示了。
在设定变量后,如果想要删除变量,那么可以通过unset命令实现:
:
~/test/bash$unset$dir
bash:
unset:
`/etc':
notavalididentifier
:
~/test/bash$unsetdir
:
~/test/bash$echo$dir
:
~/test/bash$
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
:
~/test/bash$echo$sum
2
通过命令选项i,declare能够将sum设定为整型变量。
declare还能通过以下命令选项设置变量的属性:
❑-a:
声明一个数组变量
❑-f:
声明一个函数名变量
❑-i:
声明一个整型变量
❑-r:
声明一个只读变量
❑-x:
声明一个全局变量
关于数组变量与函数将会在稍后的小节中讲解,下面讲解什么是只读变量与全局变量。
当用户创建了一个变量后,为了确保变量不会在意外情况下被二次赋值,那么可以通过事先将变量设置为只读属性来得到确保:
:
~/test/bash$declare-rcity=Shanghai
:
~/test/bash$echo$city
Shanghai
:
~/test/bash$city=Beijing
bash:
city:
readonlyvariable
:
~/test/bash$
在设置了city为只读变量后,如果想要再次对该变量进行赋值,将会得到city是只读变量的错误提示。
并且,一旦变量被设置为了只读,它将无法被去除只读属性或者是删除。
要将一个变量设置为只读属性,还能通过readonly命令实现:
:
~/test/bash$readonlynum
readonly与带有命令选项r的declare功能相同。
到目前为止,这里所有的变量都是局部变量,只能在当前bash环境中生效:
:
~/test/bash$cathelloworld.sh
#!
/bin/bash
echo"helloworld"#我的第一个脚本!
echoIcomefrom$Country
exit0
:
~/test/bash$declareCountry=China
:
~/test/bash$echo$Country
China
:
~/test/bash$./helloworld.sh
helloworld
Icomefrom
:
~/test/bash$
在脚本helloworld中,我们试着将变量Country的值显示出来,前提是在外部先创建好一个Country变量,并已经对其赋值。
可以看到,虽然在外部能够显示Country这个变量的值,它却无法在脚本中被正确引用。
现在,试着将Country设定为全局变量:
:
~/test/bash$declare-xCountry
:
~/test/bash$./helloworld.sh
helloworld
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
以HH:
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
Shanghai
:
~/test/bash$echo${City[0]}
Shanghai
:
~/test/bash$echo${City[4]}
:
~/test/bash$
在这里,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
:
~/test/bash$sum=${nums[3]}+${nums[2]}
:
~/test/bash$echo$sum
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:
00:
00ps
可以看到,特殊变量$$显示出的数字就是当前运行程序进程的PID号。
$?
变量$?
记录的是上一个命令执行后的返回码:
:
~/test/bash$ddd
bash:
ddd:
commandnotfound
:
~/test/bash$echo$?
127
:
~/test/bash$echo$?
0
这个示例先试着运行了一个错误指令,然后查看返回码,是127,具体的错误返回码含义要查看相关的资料。
再次查看返回码时,发现数值已经返回到了0,这是因为在上次查看返回码的命令成功返回,值为0。
$#与$n
这里,$n中的n是阿拉伯数字,从$1开始,每个变量都对应着调用脚本的命令参数,而$0代表的是调用脚本的名字:
:
~/test/bash$echo$0
/bin/bash
而特殊变量$#则表示调用脚本的命令参数个数,现在来看一个例子:
#!
/bin/bash
echo"$0$1$2"
echo"Thereis$#parametershere"
exit0
接着,用户试着执行这个脚本:
:
~/test/bash$bashparameter.shp1p2p3
parameter.shp1p2
Thereis3parametershere
可以看到,变量$0,$1,$2虽然没有被创建过,但是它们分别代表了调用脚本名、第一个命令参数以及第二个命令参数。
而后面的特殊变量$#则是命令参数的个数
21.2.6学习记录
本小节学习了变量的基本使用,现在,将学习心得写到脚本helloworld中去。
#!
/bin/bash
#
#helloworldbashshell学习脚本
#
############
#变量的学习#
############
#变量的创建语法为:
变量名=值
Country=China#首先创建一个变量Country
echo"$Country"#显示China
echo'$Country'#显示$Country
#使用${变量}的形式更为标准
echo"Icomefrom${Country}Shanghai"
#变量的删除使用unset
unsetCountry
echo$Country#变量Country已经不存在,显示空行
#整形变量的创建
declare-isum
#只读变量的创建
declare-rsum
#数组变量的创建
#语法:
变量名=(值1值2值3...值n)
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
先看一个例子,有助于对语句的理解:
#!
/bin/bash
echo"makeachoice(y/n):
"
readchoice
if["$choice"="y"]
then
echo"Yourchoiceisy"
exit0
elif["$choice"="n"]
then
echo"Yourchoiceisn"
exit0
else
echo"Youshouldhaveasecondthought"
exit1
fi
指令read是等待用户输入一个值赋给指定的变量,在这里,这个变量是NUM。
接下来,程序开始执行判断语句,这里判断语句的思想是:
根据户输入的字符,判断他的输入是y还是n,如果都不是,那么就报错。
在if语句中,子语句elif还有else如果不需要使用,是可以省略的。
如果这里我们只希望判断用户输入的是不是字符y,那么可以将elif与else的子语句块去掉,或者是注释掉:
#!
/bin/bash
echo"makeachoice(y/n):
"
readchoice
if["$choice"="y"]
then
echo"Yourchoiceisy"
exit0
#elif["$choice"="n"]
#then
#echo"Yourchoiceisn"
#exit0
#else
#echo"Youshouldhaveasecondthought"
#exit1
fi
这样,程序就等价于:
#!
/bin/bash
echo"makeachoice(y/n):
"
readchoice
if["$choice"="y"]
then
echo"Yourchoiceisy"
exit0
fi
test内置命令
在前面if语句的示例中,运用到了内置命令test进行条件判断。
事实上,该句中的中括号是test的简写形式。
test的语法如下:
test表达式
[表达式]
test命令对表达式进行判断,并返回一个值,来表示这个表达式是true(0),还是false
(1)。
test的简写形式是一对中括号,由它将表达式括起来,由于中括号实际上就是一个命令,所以要注意表达式与中括号之间要有空格。
表达式可以是一个,也可以是多个,当有多个表达式时,需要使用布尔操作符对它们进行分割。
-a是布尔与操作符,只有当由-a连接的条件表达式都为真是,整个表达式的值才能为真。
-o时布尔或操作符,只要当由-o连接的条件表达式中有一个为真,那么整个表达式的值就为真。
表达式中的每个元素都必须通过空格来分割。
下面列出的是test的最常用的判别式:
表21.2内置命令test的常用判别式
判别式
含义
-nstring
如果字符串string长度大于0,那么返回值为真
-zstr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 入门 引导 21
![提示](https://static.bdocx.com/images/bang_tan.gif)