bash编程实例文档格式.docx

上传人:b****2 文档编号:5761052 上传时间:2023-05-05 格式:DOCX 页数:25 大小:28.26KB
下载 相关 举报
bash编程实例文档格式.docx_第1页
第1页 / 共25页
bash编程实例文档格式.docx_第2页
第2页 / 共25页
bash编程实例文档格式.docx_第3页
第3页 / 共25页
bash编程实例文档格式.docx_第4页
第4页 / 共25页
bash编程实例文档格式.docx_第5页
第5页 / 共25页
bash编程实例文档格式.docx_第6页
第6页 / 共25页
bash编程实例文档格式.docx_第7页
第7页 / 共25页
bash编程实例文档格式.docx_第8页
第8页 / 共25页
bash编程实例文档格式.docx_第9页
第9页 / 共25页
bash编程实例文档格式.docx_第10页
第10页 / 共25页
bash编程实例文档格式.docx_第11页
第11页 / 共25页
bash编程实例文档格式.docx_第12页
第12页 / 共25页
bash编程实例文档格式.docx_第13页
第13页 / 共25页
bash编程实例文档格式.docx_第14页
第14页 / 共25页
bash编程实例文档格式.docx_第15页
第15页 / 共25页
bash编程实例文档格式.docx_第16页
第16页 / 共25页
bash编程实例文档格式.docx_第17页
第17页 / 共25页
bash编程实例文档格式.docx_第18页
第18页 / 共25页
bash编程实例文档格式.docx_第19页
第19页 / 共25页
bash编程实例文档格式.docx_第20页
第20页 / 共25页
亲,该文档总共25页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

bash编程实例文档格式.docx

《bash编程实例文档格式.docx》由会员分享,可在线阅读,更多相关《bash编程实例文档格式.docx(25页珍藏版)》请在冰点文库上搜索。

bash编程实例文档格式.docx

  $myvar='

Thisismyenvironmentvariable!

'

  以上命令定义了一个名为"

myvar"

的环境变量,并包含字符串"

"

以上有几点注意事项:

第一,在等号"

="

的两边没有空格,任何空格将导致错误(试一下看看)。

第二个件要注意的事是:

虽然在定义一个字时可以省略引号,但是当定义的环境变量值多于一个字时(包含空格或制表键),引号是必须的。

  第三,虽然通常可以用双引号来替代单引号,但在上例中,这样做会导致错误。

为什么呢?

因为使用单引号禁用了称为扩展的bash特性,其中,特殊字符和字符系列由值替换。

例如,"

!

字符是历史扩展字符,bash通常将其替换为前面输入的命令。

(本系列文章中将不讲述历史扩展,因为它在bash编程中不常用。

有关历史扩展的详细信息,请参阅bash帮助页中的“历史扩展”一节。

)尽管这个类似于宏的功能很便利,但我们现在只想在环境变量后面加上一个简单的感叹号,而不是宏。

  现在,让我们看一下如何实际使用环境变量。

这有一个例子:

  $echo$myvar

  Thisismyenvironmentvariable!

  通过在环境变量的前面加上一个$,可以使bash用myvar的值替换它。

这在bash术语中叫做“变量扩展”。

但是,这样做将怎样:

  $echofoo$myvarbar

  foo

  我们希望回显"

fooThisismyenvironmentvariable!

bar"

,但却不是这样。

错在哪里?

简单地说,bash变量扩展设施陷入了困惑。

它无法识别要扩展哪一个变量:

$m、$my、$myvar、$myvarbar等等。

如何更明确清楚地告述bash引用哪一个变量?

试一下这个:

  $echofoo${myvar}bar

  fooThisismyenvironmentvariable!

bar

  如您所见,当环境变量没有与周围文本明显分开时,可以用花括号将它括起。

虽然$myvar可以更快输入,并且在大多数情况下正确工作,但${myvar}却能在几乎所有情况下正确通过语法分析。

除此之外,二者相同,将在本系列的余下部分看到变量扩展的两种形式。

请记住:

当环境变量没有用空白(空格或制表键)与周围文本分开时,请使用更明确的花括号形式。

  回想一下,我们还提到过可以“导出”变量。

当导出环境变量时,它可以自动地由以后运行的任何脚本或可执行程序环境使用。

shell脚本可以使用shell的内置环境变量支持“到达”环境变量,而C程序可以使用getenv()函数调用。

这里有一些C代码示例,输入并编译它们--它将帮助我们从C的角度理解环境变量:

  myvar.c--样本环境变量C程序

  #include

  intmain(void){

  char*myenvvar=getenv("

EDITOR"

);

  printf("

Theeditorenvironmentvariableissetto%s\n"

myenvvar);

  }

  将上面的代码保存到文件myenv.c中,然后发出以下命令进行编译:

  $gccmyenv.c-omyenv

  现在,目录中将有一个可执行程序,它在运行时将打印EDITOR环境变量的值(如果有值的话)。

这是在我机器上运行时的情况:

  $./myenv

  Theeditorenvironmentvariableissetto(null)

  啊...因为没有将EDITOR环境变量设置成任何值,所以C程序得到一个空字符串。

让我们试着将它设置成特定值:

  $EDITOR=xemacs

  虽然希望myenv打印值"

xemacs"

,但是因为还没有导出环境变量,所以它却没有很好地工作。

这次让它正确工作:

  $exportEDITOR

  Theeditorenvironmentvariableissettoxemacs

  现在,如您亲眼所见:

不导出环境变量,另一个进程(在本例中是示例C程序)就看不到环境变量。

顺便提一句,如果愿意,可以在一行定义并导出环境变量,如下所示:

  $exportEDITOR=xemacs

  这与两行版本的效果相同。

现在该演示如何使用unset来除去环境变量:

  $unsetEDITOR

  

  截断字符串概述

  截断字符串是将初始字符串截断成较小的独立块,它是一般shell脚本每天执行的任务之一。

很多时候,shell脚本需要采用全限定路径,并找到结束的文件或目录。

虽然可以用bash编码实现(而且有趣),但标准basenameUNIX可执行程序可以极好地完成此工作:

  $basename/usr/local/share/doc/foo/foo.txt

  foo.txt

  $basename/usr/home/drobbins

  drobbins

  Basename是一个截断字符串的极简便工具。

它的相关命令dirname返回basename丢弃的“另”一部分路径。

  $dirname/usr/local/share/doc/foo/foo.txt

  /usr/local/share/doc/foo

  $dirname/usr/home/drobbins/

  /usr/home

  命令替换

  需要知道一个简便操作:

如何创建一个包含可执行命令结果的环境变量。

这很容易:

  $MYDIR=`dirname/usr/local/share/doc/foo/foo.txt`

  $echo$MYDIR

  上面所做的称为“命令替换”。

此例中有几点需要指出。

在第一行,简单地将要执行的命令以反引号括起。

那不是标准的单引号,而是键盘中通常位于Tab键之上的单引号。

可以用bash备用命令替换语法来做同样的事:

  $MYDIR=$(dirname/usr/local/share/doc/foo/foo.txt)

  如您所见,bash提供多种方法来执行完全一样的操作。

使用命令替换可以将任何命令或命令管道放在``或$()之间,并将其分配给环境变量。

真方便!

下面是一个例子,演示如何在命令替换中使用管道:

  MYFILES=$(ls/etc|greppa)

  bash-2.03$echo$MYFILES

  pam.dpasswd

  象专业人员那样截断字符串

  尽管basename和dirname是很好的工具,但有时可能需要执行更高级的字符串“截断”,而不只是标准的路径名操作。

当需要更强的说服力时,可以利用bash内置的变量扩展功能。

已经使用了类似于${MYVAR}的标准类型的变量扩展。

但是bash自身也可以执行一些便利的字符串截断。

看一下这些例子:

  $MYVAR=foodforthought.jpg

  $echo${MYVAR##*fo}

  rthought.jpg

  $echo${MYVAR#*fo}

  odforthought.jpg

  在第一个例子中,输入了${MYVAR##*fo}。

它的确切含义是什么?

基本上,在${}中输入环境变量名称,两个##,然后是通配符("

*fo"

)。

然后,bash取得MYVAR,找到从字符串"

foodforthought.jpg"

开始处开始、且匹配通配符"

的最长子字符串,然后将其从字符串的开始处截去。

刚开始理解时会有些困难,为了感受一下这个特殊的"

##"

选项如何工作,让我们一步步地看看bash如何完成这个扩展。

首先,它从"

的开始处搜索与"

通配符匹配的子字符串。

以下是检查到的子字符串:

  f

  foMATCHES*fo

  food

  foodf

  foodfoMATCHES*fo

  foodfor

  foodfort

  foodforth

  foodfortho

  foodforthou

  foodforthoug

  foodforthought

  foodforthought.j

  foodforthought.jp

  foodforthought.jpg

  在搜索了匹配的字符串之后,可以看到bash找到两个匹配。

它选择最长的匹配,从初始字符串的开始处除去,然后返回结果。

  上面所示的第二个变量扩展形式看起来与第一个相同,但是它只使用一个"

#"

--并且bash执行几乎同样的过程。

它查看与第一个例子相同的子字符串系列,但是bash从初始字符串除去最短的匹配,然后返回结果。

所以,一查到"

fo"

子字符串,它就从字符串中除去"

,然后返回"

odforthought.jpg"

  这样说可能会令人十分困惑,下面以一简单方式记住这个功能。

当搜索最长匹配时,使用##(因为##比#长)。

当搜索最短匹配时,使用#。

看,不难记吧!

等一下,怎样记住应该使用'

#'

字符来从字符串开始部分除去?

很简单!

注意到了吗:

在美国键盘上,shift-4是"

$"

,它是bash变量扩展字符。

在键盘上,紧靠"

左边的是"

这样,可以看到:

位于"

的“开始处”,因此(根据我们的记忆法),"

从字符串的开始处除去字符。

您可能要问:

如何从字符串末尾除去字符。

如果猜到我们使用美国键盘上紧靠"

右边的字符("

%),那就猜对了。

这里有一些简单的例子,解释如何截去字符串的末尾部分:

  $MYFOO="

chickensoup.tar.gz"

  $echo${MYFOO%%.*}

  chickensoup

  $echo${MYFOO%.*}

  chickensoup.tar

  正如您所见,除了将匹配通配符从字符串末尾除去之外,%和%%变量扩展选项与#和##的工作方式相同。

请注意:

如果要从末尾除去特定子字符串,不必使用"

*"

字符:

  MYFOOD="

chickensoup"

  $echo${MYFOOD%%soup}

  chicken

  在此例中,使用"

%%"

或"

%"

并不重要,因为只能有一个匹配。

还要记住:

如果忘记了应该使用"

还是"

,则看一下键盘上的3、4和5键,然后猜出来。

  可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。

试着在bash中输入以下行:

  $EXCLAIM=cowabunga

  $echo${EXCLAIM:

0:

3}

  cow

3:

7}

  abunga

  这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。

  应用字符串截断

  现在我们已经学习了所有截断字符串的知识,下面写一个简单短小的shell脚本。

我们的脚本将接受一个文件作为自变量,然后打印:

该文件是否是一个tar文件。

要确定它是否是tar文件,将在文件末尾查找模式"

.tar"

如下所示:

  mytar.sh--一个简单的脚本

  #!

/bin/bash

  if["

${1##*.}"

="

tar"

]

  then

  echoThisappearstobeatarball.

  else

  echoAtfirstglance,thisdoesnotappeartobeatarball.

  fi

  要运行此脚本,将它输入到文件mytar.sh中,然后输入"

chmod755mytar.sh"

,生成可执行文件。

然后,如下做一下tar文件试验:

  $./mytar.shthisfile.tar

  Thisappearstobeatarball.

  $./mytar.shthatfile.gz

  Atfirstglance,thisdoesnotappeartobeatarball.

  好,成功运行,但是不太实用。

在使它更实用之前,先看一下上面使用的"

if"

语句。

语句中使用了一个布尔表达式。

在bash中,"

比较运算符检查字符串是否相等。

在bash中,所有布尔表达式都用方括号括起。

但是布尔表达式实际上测试什么?

让我们看一下左边。

根据前面所学的字符串截断知识,"

将从环境变量"

1"

包含的字符串开始部分除去最长的"

*."

匹配,并返回结果。

这将返回文件中最后一个"

."

之后的所有部分。

显然,如果文件以"

结束,结果将是"

,条件也为真。

  您可能会想:

开始处的"

环境变量是什么。

很简单--$1是传给脚本的第一个命令行自变量,$2是第二个,以此类推。

好,已经回顾了功能,下面来初探"

  If语句

  与大多数语言一样,bash有自己的条件形式。

在使用时,要遵循以上格式;

即,将"

和"

then"

放在不同行,并使"

else"

和结束处必需的"

fi"

与它们水平对齐。

这将使代码易于阅读和调试。

除了"

if,else"

形式之外,还有其它形式的"

语句:

  if[condition]

  action

  只有当condition为真时,该语句才执行操作,否则不执行操作,并继续执行"

之后的任何行。

  elif[condition2]

  action2

  .

  elif[condition3]

  actionx

  以上"

elif"

形式将连续测试每个条件,并执行符合第一个真条件的操作。

如果没有条件为真,则将执行"

操作,如果有一个条件为真,则继续执行整个"

if,elif,else"

语句之后的行。

  接收自变量

  在介绍性文章中的样本程序中,我们使用环境变量"

$1"

来引用第一个命令行自变量。

类似地,可以使用"

$2"

、"

$3"

等来引用传递给脚本的第二和第三个自变量。

这里有一个例子:

  #!

/usr/bin/envbash

  echonameofscriptis$0

  echofirstargumentis$1

  echosecondargumentis$2

  echoseventeenthargumentis$17

  echonumberofargumentsis$#

  除以下两个细节之外,此例无需说明。

第一,"

$0"

将扩展成从命令行调用的脚本名称,"

$#"

将扩展成传递给脚本的自变量数目。

试验以上脚本,通过传递不同类型的命令行自变量来了解其工作原理。

  有时需要一次引用所有命令行自变量。

针对这种用途,bash实现了变量"

$@"

,它扩展成所有用空格分开的命令行参数。

在本文稍后的"

for"

循环部分中,您将看到使用该变量的例子。

  Bash编程结构

  如果您曾用过如C、Pascal、Python或Perl那样的过程语言编程,则一定熟悉"

语句和"

循环那样的标准编程结构。

对于这些标准结构的大多数,Bash有自己的版本。

在下几节中,将介绍几种bash结构,并演示这些结构和您已经熟悉的其它编程语言中结构的差异。

如果以前编程不多,也不必担心。

我提供了足够的信息和示例,使您可以跟上本文的进度。

  方便的条件语句

  如果您曾用C编写过与文件相关的代码,则应该知道:

要比较特定文件是否比另一个文件新需要大量工作。

那是因为C没有任何内置语法来进行这种比较,必须使用两个stat()调用和两个stat结构来进行手工比较。

相反,bash内置了标准文件比较运算符,因此,确定“/tmp/myfile是否可读”与查看“$myvar是否大于4”一样容易。

  下表列出最常用的bash比较运算符。

同时还有如何正确使用每一选项的示例。

示例要跟在"

之后。

例如:

  if[-z"

$myvar"

  echo"

myvarisnotdefined"

  运算符描述示例

  文件比较运算符

  -efilename如果filename存在,则为真[-e/var/log/syslog]

  -dfilename如果filename为目录,则为真[-d/tmp/mydir]

  -ffilename如果filename为常规文件,则为真[-f/usr/bin/grep]

  -Lfilename如果filename为符号链接,则为真[-L/usr/bin/grep]

  -rfilename如果filename可读,则为真[-r/var/log/syslog]

  -wfilename如果filename可写,则为真[-w/var/mytmp.txt]

  -xfilename如果filename可执行,则为真[-L/usr/bin/grep]

  filename1-ntfilename2如果filename1比filename2新,则为真[/tmp/install/etc/services-nt/etc/services]

  filename1-otfilename2如果filename1比filename2旧,则为真[/boot/bzImage-otarch/i386/boot/bzImage]

  字符串比较运算符(请注意引号的使用,这是防止空格扰乱代码的好方法)

  -zstring如果string长度为零,则为真[-z"

  -nstring如果string长度非零,则为真[-n"

  string1=string2如果string1与string2相同,则为真["

onetwothree"

  string1!

=string2如果string1与string2不同,则为真["

!

="

  算术比较运算符

  num1-eqnum2等于[3-eq$mynum]

  num1-nenum2不等于[3-ne$mynum]

  num1-ltnum2小于[3-lt$mynum]

  num1-lenum2小于或等于[3-le$mynum]

  num1-gtnum2大于[3-gt$mynum]

  num1-genum2大于或等于[3-ge$mynum]

  有

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

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2