在Linux世界驰骋系列之二——Shell编程

2012年4月2日 发表评论 阅读评论

http://tech.ddvip.com/2007-03/117369025020923_9.html

6. 预先定义的特殊变量

  在Shell中,预先定义了几个有特殊含义的Shell变量,它们的值只能由Shell根据实际情况进行赋值,而不能通过用户重新设置。下面给出这些特殊变量的表示形式及意义:

  $# 命令行上实际参数的个数,但不包含Shell脚本名。

  $?上一条命令执行后的返回值(也称作 “退出码”)。它是一个十进制数。多数Shell命令执行成功时,则返回值为0;如果执行失败,则返回非0值。

  $$ 当前进程的进程号。

  $! 上一个后台命令对应的进程号,这是一个由1~5位数字构成的数字串。

  $- 由当前Shell设置的执行标志名组成的字符串。例如:

set -xv

  这个命令行给Shell设置了标志-x和-v(用于跟踪输出)。

  $* 表示在命令行中实际给出的所有实参字符串,它并不仅限于9个实参。

$ @ 它与$*基本功能相同,但“$@”与“$*”不同

7.环境变量

  Linux环境(也称为Shell环境)由许多变量及这些变量的值组成。这些变量和变量的值决定了用户环境的外观。注意,如果要使用环境变量或其它Shell变量的值,必须在变量名之前加上一个“$”符号,不能直接使用变量名。

  常用的环境变量如下:

  HOME 用户主目录的全路径名。

MAIL 系统信箱的路径。

  PATH 查找命令的目录列表。PATH变量包含带冒号分界符的字符串,这些字符串指向含有所使用命令的目录。

  PS1 Shell的主提示符。bash默认的主提示符一般为“s-v$ ”。其中,s表示Shell的名称;v表示bash的版本号。当然,也可以随意设置PS1的值,例如:

PS1="Enter Command> "

  则主提示符改成“Enter Command> ”。

  PWD 当前工作目录的路径,它指出目前在Linux文件系统中处在什么位置。

  SHELL 当前使用的Shell,它也指出Shell解释程序放在什么地方。

  TERM 终端类型。

  可以使用unset命令删除一个环境变量(如NAME):

$ unset NAME

  可以创建一个新的环境变量,或者改变一个已有的环境变量的值,其形式与设置一般变量相同。如果变量值的字符串中带有空格等特殊字符,需要用引号把整个字符串括起来。利用export命令可以将这些变量导出,使它们成为公用量,如:

export HOME HZ LOGNAME TERM

  可以利用env命令列出所有的环境变量,包括本进程及以前的“祖先进程”所导出的变量。

  8.参数置换变量

  参数置换变量是另一种为变量赋值的方式,其一般形式是:

变量2=$ {变量1 op 字符串}

  其中,op表示操作符,它可以是下列四个操作符之一“: :-”、“: =” 、“: +” 和“: ?”。变量2的值取决于变量1(参数)是否为空串、利用哪个操作符及字符串的取值。在操作符的前后不留空格。

  命令历史

  bash提供了命令历史功能,即系统为每个用户维护一个命令历史文件(~/.bash_history),它在注册用户的主目录(用~表示)之下。该文件由编号的表格构成。每当注册后,用户输入命令并执行它时,该命令就自动地加到这个命令历史表中。

使用命令历史机制,用户可以方便地调用或者修改以前的命令,可以把全部或部分先前命令作为新命令予以快捷执行。这一功能称为历史替换(history substitution)。

  ◆history命令可以显示命令历史表中的命令。其语法格式是:

history [option][arg ?]

   (1)如果不带任何参数,则history命令会显示历史命令的清单(包括刚输入的history命令)。所有这些命令都被称作事件,一个事件表示一个 操作已经发生,即一个命令已被执行。显示的各行命令之前的数字表示相应命令行在命令历史表中的序号,称为历史事件号。历史事件号从1开始顺序向下排,最后 执行的命令的事件号最大。

  (2)如果history 后给出一个正整数,例如:

history 50

  那么,就只显示历史表中的最后50行命令。

  (3)如果history后给出一个文件名,例如:

history al

  那么,就把al作为历史文件名。

   ◆执行历史命令是命令替换之一,它以字符“!”开头、后随1个或多个字符来定义用户所需的某种类型的历史命令。它可以出现在输入行的任何地方,除非已在 进行历史替换。如果在“!”之前加上反斜线“”,或者在其后跟着空格、制表符、换行符、等号“=”或开括号“(”,那么“!”就作为普通字符对待,失去特 殊意义。

  历史替换可以作为输入的命令行的一部分或全体。当输入行的正文中包含历史替换时,将在完成相应的替换后,在终端上显示输入的命令行,从而用户可以看到实际执行的命令(显示命令后立即执行)。

  ◆在默认方式下,bash使用用户主目录下面的文件“.bash_history”来保存命令历史。但是,用户也可以通过重新为环境变量HISTFILE赋值来改变存放历史命令的文件。例如:

$ HISTFILE="/home/mengqc/.myhistory"

  历史文件中能够保留的命令个数有限,其默认值是500。如果用户输入的命令太多,超过限定值,那么最早输入的命令就会从历史表中删除,而新输入的命令会加到该表尾部。用户可以利用HISTSIZE变量重新设定该值。例如:

$ HISTSIZE=600

  通常用户不必对命令历史表进行管理(如设置HISTSIZE的值等),由系统自动管理。利用命令历史功能,用户可以对先前输入的命令重新进行编辑、修改和执行,从而简化用户的操作。

  别名

  使用别名可以简化输入,方便用户。对于常用的选项或参数较多的固定命令采用别名替换,既缩短击键次数,又减少出错机率。

  定义别名要使用Shell内部命令alias,其一般语法格式为:

alias [name[=value]]…

  如果没有指定参数,将在标准输出(屏幕)上显示别名清单,其格式为name=value,其中name是用户(或系统)定义的别名名称,value是别名所代表的内容。注意,在赋值号“=”两边不能有空格。

  例如:

$ alias ll=' ls -l '

   定义了别名ll,它代表“ls -l”。当输入ll命令后,Shell将寻找它们所维护的别名表(放在内存中的一个内部表格)。若在该表中找到命令行的第一个字段(即“ll”)时,该命 令就会被别名定义的内容所替换。定义别名时,往往用单引号将它代表的内容括起来,从而防止Shell对其中的内容产生歧义,如对空格和特殊字符另作解释。

  如果想取消先前定义的别名,可使用如下命令:

unalias name…

  执行后,就从别名表中删除由name指定的别名。

  unalias也可以在一个命令上同时取消多个别名的定义,只须在unalias之后依次列出要取消的别名名称。也可以一次将所有的别名都从别名表中删除,使用如下命令:

unalias -a

  Shell特殊字符

  Shell中除使用普通字符外,还使用了一些特殊字符,它们有特定的含义,如通配符“*”和“?”、管道线(|)及单引号、双引号等。在使用时应注意它们表示的意义和作用范围。

  1.一般通配符

  通配符用于模式匹配,如文件名匹配、路径名搜索、字符串查找等。常用的通配符有四种:

  * 匹配任意字符0次或多次出现。例如,f*可以匹配以f 打头的任意字符串。但应注意,文件名前面的圆点( . ) 和路径名中的斜线( / )必须显式匹配。

  ? 匹配任意一个字符,例如,f ?匹配f1、fa、fb等,但不能匹配 f 、fabc、 f12等。

  [ ] 其中有一个字符组,它匹配该字符组所限定的任何一个字符。该字符组可以由直接给出的字符组成,也可以由表示限定范围的起始字符、终止字符及中间一个连字符(-)组成。例如,f[a-d]与f[abcd]作用相同。

  ! 表示不在一对方括号中所列出的字符。例如,f[!1—9].c 表示以f打头,后面一个字符不是数字1至9的.c文件名,它匹配fa.c、fb.c、fm.c等。

  在一个正则表达式中,可以同时使用“*”和“?”。

  2.模式表达式

  模式表达式是那些包含一个或多个通配符的字。bash除支持一般通配符外,还提供了特有的扩展模式匹配表达式,其形式和含义如下:

   (1)*(模式表) 匹配给定模式表中“模式”的0次或多次出现,各模式之间以“|”分开。例如,file*(.c|.o)将匹配文件file、file.c、file.o、 file.c.c、file.0.0、file.c.o、file.o.c等,但不匹配file.h或file.s等。

  (2)+(模式表) 匹配给定模式表中“模式”的1次或多次出现,各模式之间以“|”分开。例如,file+(.c | .o)匹配文件file.c、file.o、file.c.o、file.c.c等,但不匹配file。

(3)?(模式表) 匹配模式表中任何一种“模式”的0次或1次出现,各模式之间以“|”分开。例如,file?(.c|.o)只匹配file、file.c和file.0,它不匹配多个模式或模式的重复出现,即不匹配file. c. c、file. c. 0等。

  (4)@(模式表) 仅匹配模式表中给定“模式”的一次出现,各模式之间以“|”分开。例如,file@(.c|.0)匹配file.c和file.0,但不匹配file、file.c.c、file.c.o等。

  (5)!(模式表) 除给定模式表中的一个“模式”之外,它可以匹配其它任何东西。

   可以看出,模式表达式的定义是递归的,每个表达式中都可以包含一个或多个模式。例如file*( .[cho]|.sh)是合法的模式表达式。但在使用时应注意,由于带“*”和“+”的表达式可以匹配给定模式的组合,若利用此种表达式去删除文件就存在 危险,有可能误将系统配置文件删除。因此,必须小心使用。

  3.引号

  在Shell中引号分为三种:单引号、双引号和倒引号。

  (1)双引号

   由双引号括起来的字符,除$、倒引号(`)和反斜线()仍保留其特殊功能外,其余字符均作为普通字符对待。“$”表示变量替换,即用其后指定的变量的值 来代替$和变量;倒引号表示命令替换;仅当“”后面的字符是下述字符之一时,“”才是转义字符,这些字符是:“$”、“`”、“"”、“”或换行符。转义 字符告诉Shell不要对其后面的那个字符进行特殊处理,只是当作普通字符。例如:

$ echo "My current dir is `pwd` and logname is $LOGNAME"
My current dir is /home/mengqc and logname is mengqc

(2)单引号

  由单引号括起来的字符都作为普通字符出现。例如,

$ echo 'The time is ` date ` , the file is $HOME/abc '
The time is ` date ` , the file is $HOME/abc

  (3)倒引号

  倒引号括起来的字符串被shell解释为命令行,在执行时,Shell会先执行该命令行,并以它的标准输出结果取代整个倒引号部分。在前面示例中已经见过。例如,

$ echo current directory is ` pwd `
current directory is /home/mengqc

  4.注释

  Shell程序中以“#”开头的正文行表示注释。例如:

#!/bin/bash
# If no arguments, then listing the current directory.
# Otherwise, listing each subdirectory.
if test $# = 0
then ls ·
else
for i 
do
ls -l $i | grep '^d'   
done
fi

  上面程序由if语句构成,其中else部分是for循环语句。其功能是检测位置参数个数,若等于0,则列出当前目录本身;否则,对于每个位置参数显示其所包含的子目录。

   上面代码中,第一行#!/bin/bash表示下面的脚本是用bash编写的,必须调用bash程序对它解释执行。后面两行以“ # ”开头,表示这是注释行。注释行可用来说明程序的功能、结构、算法和变量的作用等,增加程序的可读性。在执行时Shell将忽略注释行。

  命令执行操作符

  ◆多条命令可以在一行中出现。它们可以从左到右顺序执行。此时,各条命令之间应以分号( ;)隔开,如:

pwd ; who | wc -l ; cd /usr/bin

  ◆在相邻命令间可存在逻辑关系,即逻辑“与”和逻辑“或”。


转载请注明来自:[MSN Spaces]http://msn.shandian.biz/190.html

  1. 本文目前尚无任何评论.