shell变量

来源:互联网 发布:合肥百度seo教程 编辑:程序博客网 时间:2024/05/22 13:35
13.10  变量
13.10.1  变量类型
变量可分为两类:局部变量和环境变量。局部变量只在创建它们的shell中可用。而环境变量则可以在创建它们的shell及其派生出来的任意子进程中使用。有些变量是用户创建的,其他的则是专用shell变量。
13.10.2  命名惯例
变量名必须以字母或下划线字符开头。其余的字符可以是字母、数字(0~9)或下划线字符。任何其他的字符都标志着变量名的终止。名字是大小写敏感的。给变量赋值时,等号周围不能有任何空白符。为了给变量赋空值,可以在等号后跟一个换行符。创建一个局部变量最简单的格式是给一个变量赋值,如以下格式所示。
格式
变量=值
范例13-49
name=Tommy
13.10.3  内置命令declare
有两个内置命令可以用来创建变量,它们是declare和typeset,其选项可以控制变量设置的方式。typeset命令(来自Korn shell)的功能和declare命令(bash)完全一样。bash文档中指出,“提供typeset命令是为了和Korn shell兼容。但是不建议使用它,而应使用内置命令declare” 12。因此从这一点来说,我们将使用declare命令(即使我们使用typeset也一样方便)。
  不带任何参数时,declare将列出所有已设置的变量。通常只读变量不能被重新赋值或复位。如果只读变量是用declare创建的,那它们不可以被复位,但可以被重新赋值。整型变量也可以用declare赋值。
格式
declare  变量=值
范例13-50
declare name=Tommy
表13-13  declare选项
选    项
 含    义
 
-a 13
 将变量当作一个数组。即,分配元素
 
-f
 列出函数的名称和定义
 
-F 
 只列出函数名
 
-i
 将变量设为整型
 
-r
 将变量设为只读
 
-x
 将变量名输出到子shell中
 


13.10.4  局部变量和作用域
变量的作用域指变量在一个程序中的哪些地方可见。对于shell来说,局部变量的作用域被限定在创建它们的shell中。
给变量赋值时,等号前后不能有空白符。如果要给变量赋空值,可以在等号后跟一个换行符 。14
变量前的美元符用来提取存储在变量里的值。
local函数可以用来创建局部变量,但仅限于在函数内使用(请参见13.16.1节,“定义函数”)。
设置局部变量  局部变量可以通过简单地赋予它一个值或一个变量名来设置,或者如范例13-51所示用declare内置函数来设置。
范例13-51
1   $ round=world or declare round=world
    $ echo $round
    world
2   $ name="Peter Piper"
    $ echo $name
    Peter Piper
3   $ x=
    $ echo $x
4   $ file.bak="$HOME/junk"
    bash: file.bak=/home/jody/ellie/junk: not found
说明
1. 将局部变量round赋值为world。如果遇到变量名前面是个美元符的情况,shell就执行变量替换。该命令显示变量round的值(不要混淆提示符($)和用来执行变量替换的$符)。
2. 局部变量name被赋值为“Peter Piper”。必须用引号来保护空白符,这样,shell分析命令行时才不会将这个字符串看成是两个词。该命令显示变量name的值。
3. 这条命令没有给变量x赋值,因此x被赋值为空。结果显示一个空值,即空字符串。
4. 变量名中出现句点是非法的。变量名可以使用的字符只能是数字、字母和下划线。因此,shell尝试将这个字符串作为一条命令来执行。
范例13-52
1   $ echo $$
    1313
2   $ round=world
    $ echo $round
    world
3   $ bash            # Start a subshell
4   $ echo $$
    1326
5   $ echo $round
6   $ exit           # Exits this shell, returns to parent shell
7   $ echo $$
    1313
8   $ echo $round
    world
说明
1. 双美元符变量的值是当前shell的PID。本例中这个shell的PID是1313。
2. 将局部变量round赋值为字符串world,并打印该变量的值。
3. 另外启动一个bash shell,这个shell被称为子shell(subshell或child shell)。
4. 当前这个shell的PID时1326,其父shell的PID则是1313。
5. 局部变量round在这个shell中没有定义,因此打印了一个空行。
6. exit命令终止当前shell并返回父shell(也可以按Ctrl+D组合键退出当前shell)。
7. 返回到父shell。显示它的PID。
8. 显示变量round的值。它是这个shell的局部变量。
设置只读变量  只读变量是不能被重新定义或复位的特殊变量。但是,如果使用了declare函数,只读变量可以被重新定义,但不能被复位。
范例13-53
1   $ name=Tom
2   $ readonly name
    $ echo $name
    Tom
3   $ unset name
    bash: unset: name: cannot unset: readonly variable
4   $ name=Joe
    bash: name: readonly variable
5   $ declare -r city='Santa Clara'
6   $ unset city
    bash: unset: city: cannot unset: readonly variable
7   $ declare city='San Francisco'   # What happened here?
    $ echo $city
    San Francisco
说明
1. 局部变量name的值被设为Tom。
2. 将变量name设为只读。
3. 不能复位只读变量。
4. 不能重新定义只读变量。
5. declare内置命令给只读变量city赋值Santa Clara。当所赋值串中包含空白符时必须用引号。
6. 因其是只读变量,所以不能被复位。
7. 当只读变量是由declare命令创建时,它不可以被复位,但可以被重新赋值。
13.10.5  环境变量
环境变量可用在创建它们的shell和从该shell派生的任意子shell或进程中。它们通常被称为全局变量,以区别于局部变量。通常,环境变量应该大写。环境变量是已经用export内置命令导出的变量。
变量被创建时所处的shell被称为父shell。如果父shell又启动了一个shell,这个新的shell被称作子shell。环境变量将传递给从创建它们的shell里启动的任意子进程。它们从父亲传递给儿子再到孙子等,但是不可向其他方向传递。比如,一个子进程可以创建环境变量,但不能将它传回给它的父进程,只能传给它的子进程 15。有一些环境变量,比如HOME、LOGNAME、PATH和SHELL,在用户登录之前就已经被/bin/login程序设置好了。通常,环境变量定义并保存在用户主目录下的.bash_profile文件中。请参见表13-14中列出的环境变量。
表13-14  bash环境变量
变  量  名
 含    义
 
_(下划线)
 上一条命令的最后一个参数
 
BASH
 展开为调用bash实例时使用的全路径名
 
BASH_ENV
 和ENV一样,但只可在bash 2.0或更高版本中设置 16
 
BASH_VERSINFO
 使用2.0以上版本的bash时,展开为版本信息 16
 
BASH_VERSION
 展开为当前bash实例的版本号
 
CDPATH
 cd命令的搜索路径。它是以冒号分隔的目录列表,shell通过它来搜索cd命令指定的目标目录。例如.:~:/usr
 
COLUMNS
 设置该变量就给shell编辑模式和选择的命令定义了编辑窗口的宽度
 
DIRSTACK
 在2.0或以上版本的bash中,代表目录栈的当前内容 
 
EDITOR
 内置编辑器emacs、gmacs或vi的路径名
 
ENV
 每一个新的bash shell(包括脚本)启动时执行的环境文件。通常赋予这个变量的文件名是.bashrc。ENV的值被解释为路径名前,shell先要对其进行参量扩展,命令替换和算术扩展
 
EUID
 展开为在shell启动时被初始化的当前用户的有效ID
 
FCEDIT
 fc命令的默认编辑器名
 
FIGNORE
 执行文件名补全时可忽略的以冒号分隔的后缀列表。以FIGNORE中任一项为后缀的文件名被从匹配的文件名列表中排除。例如值为.o:~
 
FORMAT
 用来格式化在命令管道上的time关键字的输出
 
GLOBIGNORE
 在文件名扩展(称为globbing)时被忽略的文件列表 
 
GROUPS
 当前用户所属的组 
 
HISTCMD
 当前命令的历史编号或在历史清单中的序号。如果HISTCMD被复位,即使它随后就会重置,也将失去它的特殊属性
 
HISTCONTROL
 如果设置了ignorespace值,以一个空格符开头的行将不会进入历史清单。如果设置了ignoredups值,那和前一个历史行匹配的行不会进入。值ignoreboth结合了这两个选项。如果被复位,或设置成除了上面所说的任意其他值时,所有被解释器所读的行都将保存到历史清单中
 
  HISTFILE
 指定保存命令行历史的文件。默认值是~/.bash_history。如果被复位,交互式shell退出时将不保存命令行历史
 


(续表)   
变  量  名
 含    义
 
HISTFILESIZE
 历史文件能包含的最大行数。当给这个变量赋值后,如果有必要,历史文件将被截尾,以使包含的行数不超过这个数。默认值是500
 
HISTSIZE
 记录在命令行历史文件中的命令数。默认是500
 
HOME
 主目录。未指定目录时,cd命令将转向该目录
 
HOSTFILE
 包含一个格式和/etc/hosts一样的文件的名称,当shell需要补全一个主机名时将读取该文件。文件可以交互式更改。下一次试图补全主机名时,bash将新文件的内容添加到已经存在的数据库中
 
HOSTTYPE
 自动设置正在运行bash的机器的类型。默认值是由系统决定的
 
IFS
 内部字段分隔符,一般是空格符、制表符和换行符,用于由命令替换,循环结构中的表和读取的输入产生的词的字段划分
 
IGNOREEOF
 控制shell接收到单独一个EOF字符作为输入时的行为。如果设置,它的值就是shell退出前在一个输入行的最前面键入的连续EOF字符的个数。如果变量存在但没有一个数字值,或没有值,那么默认值是10。如果它不存在,EOF意味着给shell的输入的终止。它只在交互式shell中有效
 
INPUTRC
 readline启动文件的文件名,取代默认的~/.inputrc
 
LANG
 用来为没有以LC_开头的变量明确选取的种类确定locale类
 
LC_ALL
 忽略LANG和任何其他LC_变量的值 
 
LC_COLLATE
 确定对路径名扩展的结果进行排序时的整理顺序,以及匹配文件名与模式时的范围表达式,等价类和整理序列的行为 
 
LC_MESSAGES
 确定用于转换前面有一个$的双引号串的locale 
 
LINENO
 每次shell在一个脚本或函数中替换代表当前连续行号(从1开始)的十进制数时,都将引用该参数 
 
MACHTYPE
 包含一个描述正在运行bash的系统的串
 
MAIL
 如果该参数被设置为某个邮件文件的名称,而MAILPATH未被设置,当邮件到达MAIL指定的文件时,shell会通知用户
 
MAIL_WARNING
 如果设置了该变量,当bash发现用于检查邮件的文件在上次检查后又被访问了,将打印消息“The mail in [filename where mail is stored] has been read”
 
MAILCHECK
 这个参数定义shell将隔多长时间(以秒为单位)检查一次由参数MAILPATH或MAILFILE指定的文件,看看是否有邮件到达。默认值是600秒(10分钟)。如果将它设为0,shell每次输出主提示符之前都会去检查邮件
 
MAILPATH
 由冒号分隔的文件名列表。如果设置了这个参数,只要有邮件到达任何一个由它指定的文件,shell都会通知用户。每个文件名后面都可以跟一个百分号和一条消息,当文件修改时间发生变化时,shell会显示这条消息。默认的消息是:You have mail
 


                                                (续表)   
变  量  名
 含    义
 
OLDPWD
 前一个工作目录
 
OPTARG
 上一个由getopts内置命令处理的选项参数的值
 
OPTERR
 如果设置成1,显示来自getopts内置命令的错误信息
 
OPTIND
 下一个由getopts内置命令处理的参数的序号
 
OSTYPE
 自动设置成一个串,该串描述正在运行bash的操作系统。默认值由系统决定
 
PATH
 命令搜索路径。一个由冒号分隔的目录列表,shell用它来搜索命令。默认路径由系统决定,并且由安装bash的管理员设置。一个普通值为
/usr/gnu/bin:/usr/local/bin:/usr/ucb:/usr/bin:
 
PIPESTATUS
 一个数组,包含一列最近在管道执行的前台作业的进程退出状态值
 
PPID
 父进程的进程ID
 
PROMPT_COMMAND
 赋给这个变量的命令将在主提示符显示前执行
 
PS1
 主提示符串,默认值是$
 
PS2
 次提示符串,默认值是>
 
PS3
 与select命令一起使用的选择提示符串,默认值是#?
 
PS4
 当开启追踪时使用的调试提示符串,默认值是+。追踪可以用set –x开启
 
PWD
 当前工作目录。由cd设置
 
RANDOM
 每次引用该变量,就产生一个随机整数。随机数序列可以通过给RANDOM赋值来初始化。如果RANDOM被复位,即使随后再设置,它也将失去特定的属性
 
REPLY
 当没有给read提供参数时设置
 
SECONDS
 每次SECONDS被引用,将返回调用shell以来的秒数。如果给SECONDS赋一个值,以后引用返回的值将是赋值以来的秒数加上所赋的值。如果SECONDS被复位,即使随后再设置,它也将失去特定的属性
 
SHELL
 当调用shell时,它扫描环境变量以寻找该名字。shell给PATH、PS1、PS2、MAILCHECK和IFS设置默认值。HOME和MAIL由login(1)设置
 
SHELLOPTS
 包含一列开启的shell选项,比如braceexpand、hashall、monitor等
 
SHLVL
 每启动一个bash实例时将其加1
 
TMOUT
 设置退出前等待输入的秒数
 
UID
 展开为当前用户的用户ID,在shell启动时初始化
 


设置环境变量 如果想设置环境变量,就要在给变量赋值之后或设置变量时使用export命令(参见表13-15)。带-x选项的declare内置命令也可完成同样的功能(输出变量时不要在变量名前面加$)。
表13-15  export命令和它的选项
选    项
 值
 
--
 标志着选项末尾,余下的参数被视为变量
 
-f
 名-值对被看作函数,而不是变量
 
-n
 将一个全局(导出)变量转换成局部变量。之后该变量将不能被导出到子进程中
 
-p
 显示所有的全局变量
 


格式
export变量=值
变量=值; export变量
declare –x 变量=值
范例13-54
export NAME=john
PS1= '/d:/W:$USER> ' ; export PS1
declare -x TERM=sun
范例13-55
1   $ export TERM=sun    # or declare -x TERM=sun
2   $ NAME="John Smith"
    $ export NAME
    $ echo $NAME
    John Smith
3   $ echo $$
    319             # pid number for parent shell
4   $ bash         # Start a subshell
5   $ echo $$
    340             # pid number for new shell
6   $ echo $NAME
    John Smith
7   $ declare -x NAME="April Jenner"
    $ echo $NAME
    April Jenner
8   $ exit          # Exit the subshell and go back to parent shell
9   $ echo $$
    319             # pid number for parent shell
10  $ echo $NAME
    John Smith
说明
1. 给TERM变量赋值sun。同时输出它。现在,由这个shell启动的所有进程都将继承这个变量。也可以用declare –x来完成同样的功能。
2. 定义并输出变量NAME,让它可以被当前shell启动的所有子shell使用。
3. 打印当前shell的PID的值。
4. 启动一个新的bash。这个新shell称为子shell。原来那个shell称为父shell。
5. 新的bash shell的PID保存在变量$$中,回显这个变量的值。
6. 在父shell中设置的变量NAME导出给这个新shell,这条命令显示它的值。
7. 内置的declare函数是设置变量的另一种方式。用-x开关,declare可以输出变量。该变量被重新设置为April Jenner。这个变化将输出到所有的子shell,但不会影响父shell。输出的变量不会向上传递给父shell。
8. 退出这个bash子shell。
9. 再次显示父shell的PID。
10. 变量NANE的值还跟原来一样。从父shell输出到子shell时,变量保持它们的值不变。子shell不可能改变父shell的变量的值。
13.10.6  复位变量
只要不被设为只读,局部变量和环境变量都可以用unset命令复位。
范例13-56
unset name; unset TERM
说明
unset命令从shell存储器中删除变量。
13.10.7  显示变量值
echo命令  内置echo命令将它的参数显示到标准输出上。echo加-e选项,允许使用大量控制输出外观的转义序列。表13-16列出了echo选项和转义序列。
表13-16  echo选项和转义序列
选    项
 含    义
 
-e 
 允许解释下面列出的转义序列
 
-E
 禁止解释这些转义字符,即使在那些默认解释它们的系统上(bash 2.x) 17
 
-n
 删除输出结果中行尾的换行符
 
转义序列
 
/a
 报警(铃) 
 
/b
 退格
 
/c
 不带换行符打印一行
 
/f
 换页
 
/n
 换行
 
/r
 回车
 
/t
 制表符
 
/v
 纵向制表符
 
//
 反斜杠
 
/nnn
 ASCII码是nnn(八进制)的字符
 


当使用转义序列时,不要忘记用-e开头。
范例13-57
1   $ echo The username is $LOGNAME.
    The username is ellie.
2   $ echo -e "/t/tHello there/c"
                 Hello there$
3   $ echo -n "Hello there"
    Hello there$
说明
1. echo命令将它的参数打印到屏幕上。shell会在执行echo命令之前先进行变量替换。
2. 带-e选项的echo命令支持转义序列,和C编程语言类似。$是shell提示符。
3. 当-n选项打开时,不带换行符打印一行。这个版本的echo不支持转义序列。
printf命令  printf 18的GNU版本可以用来编排打印输出的格式。它以和C printf函数相同的方式打印格式串。格式由一个串组成,它包含描述打印输出结果的格式指令。格式指令由带格式符(diouxXfeEgGcs)的%指定,%f代表一个浮点数,%d则代表一个(十进制)整数。
要得到printf格式符的完整清单以及如何使用它们,可以在命令行键入:printf --help。键入printf --version就可以知道使用的printf是什么版本。如果使用的是bash 2.x,内置printf命令所用的格式和/usr/bin下的printf可执行程序完全一样。
格式
printf格式[参数…]
范例13-58
printf "%10.2f%5d/n" 10.5  25
表13-17  printf命令的格式符
格  式  符
 值
 
/"
 双引号
 
/0NNN
 一个八进制字符,这里NNN代表0~3位
 
//
 反斜杠
 
/a
 报警或蜂鸣
 
/b
 退格
 
/c
 不产生更多的输出
 
/f
 换页
 
/n
 换行
 
/r
 回车
 


                                    (续表)   
格 式 说 明
 值
 
/t
 水平制表符
 
/v
 垂直制表符
 
/xNNN
 十六进制字符,这里NNN是1~3位
 
%%
 单个百分号
 
%b
 字符串参数,也对/转义字符进行解释
 


范例13-59
1   $ printf --version
    printf (GNU sh-utils) 1.16
2   $ type printf
    printf is a shell builtin
3   $ printf "The number is %.2f/n" 100
    The number is 100.00
4   $ printf "%-20s%-15s%10.2f/n" "Jody" "Savage" 28
    Jody                Savage              28.00
5   $ printf "|%-20s|%-15s|%10.2f|/n" "Jody" "Savage" 28
    Jody                |Savage          |    28.00|
6   $ printf "%s's average was %.1f%%./n" "Jody" $(( (80+70+90)/3 ))
    Jody's average was 80.0%.
说明  
1. 显示printf命令的GNU版本。
2. 如果使用的是bash 2.x,printf是一个内置命令。
3. 按照说明符%.2f指定的格式,参数100以保留两位小数的浮点数形式输出。与C函数不同的是,这里不需要用逗号来分隔参数。
4. 格式串指明将进行3个变换:第一个是%-20s(一个左对齐,长度为20的字符串),接着是%-15s(一个左对齐,长度为15的字符串),最后一个则是%10.2f(一个右对齐,长度为10的浮点数,其中的一个字符是句点,最后两个字符是小数点右边的两个数)。参数按对应%号的顺序被格式化,因此字符串Jody对应第一个%,字符串Savage对应第二个%,数字28则对应最后一个%号。
5. 该行和第4行一样,唯一的区别是增加了竖杠以说明串是左对齐还是右对齐的。
6. printf命令格式化字符串Jody和算术扩展的结果(请参见13.13节,“算术扩展”)。需要两个百分号(%%)才能输出一个百分号(%)。
13.10.8  变量扩展修饰符
我们可以用一些专用修饰符来测试和修改变量。修饰符首先提供一个简单的条件测试,用来检查某个变量是否已经被设置,然后根据测试结果给变量赋一个值。请参见表13-18列出的变量修饰符。
表13-18  变量修饰符
修  饰  符
 值
 
${variable:-word}
 如果变量variable已被设置且非空,则代入它的值。否则,代入word
 
${variable:=word}
 已被设置且值非空,就代入它的值。否则,将variable的值设为word。始终代入variable的值。位置参量不能用这种方式赋值
 
${variable:+word}
 如果变量variable已被设置且值非空,代入word。否则,什么都不代入(代入空值)
 
${variable:?word}
 如果变量variable已被设置且值非空,就代入它的值。否则,输出word并且从shell退出。如果省略了word,就会显示信息:parameter null or not set
 
${variable:offset}
 获得变量variable值中位置从offset开始的子串,偏移为从0到串的末尾 19
 
${variable:offset:length}
 获得变量variable值中位置从offset开始长度为length的子串
 


和冒号配合使用时,修饰符(-、=、+、?)检查变量是否尚未赋值或值为空。不加冒号时,值为空的变量也被认为已设置。
范例13-60
(临时替换默认值)
1   $ fruit=peach
2   $ echo ${fruit:–plum}
    peach
3   $ echo ${newfruit:–apple}
    apple
4   $ echo $newfruit
5   $ echo $EDITOR       # More realistic example
6   $ echo ${EDITOR:-/bin/vi}
    /bin/vi
7   $ echo $EDITOR
8   $ name=
    $ echo ${name-Joe}
9   $ echo ${name:-Joe}
    Joe
说明
1. 将变量fruit的值设为peach。
2. 这个专用修饰符将检查变量fruit是否已被设置。如果fruit已被设置,就显示它。否则,用plum替换fruit,并显示该值。
3. 变量newfruit未曾被设置。值apple将暂时替换newfruit。
4. 上一行的设置是暂时的,因此,变量newfruit仍未被设置。
5. 环境变量EDITOR尚未被设置。
6. 修饰符:-将/bin/vi替换为EDITOR。
7. EDITOR未曾被设置过,因此什么都不会打印。
8. 变量name被设为空值。因为修饰符前面没有冒号,变量即使为空也被认为是设置过的,所以没有把新的值Joe赋给变量name。
9. 冒号使得修饰符检查变量是否未设置或为空。只要是这两种情况之一,就用值Joe替换name。
范例13-61
(永久替换默认值)
1   $ name=
2   $ echo  ${name:=Peter}
    Peter
3   $ echo $name
    Peter
4   $ echo ${EDITOR:=/bin/vi}
    /bin/vi
5   $ echo $EDITOR
    /bin/vi
说明
1. 赋给变量name一个空值。
2. 用修饰符:=将检查变量name是否尚未被设置。如果已经被设置过了,就不会被改变。如果尚未设置或值为空,就将等号右边的值赋给它。由于之前已将变量name设置为空,所以现在要把Peter赋给它。这个设置是持久的。
3. 变量name的值还是Peter。
4. 把变量EDITOR设置为/bin/vi。
5. 显示变量EDITOR的值。
范例13-62
(临时替换值)
1   $ foo=grapes
2   $ echo ${foo:+pears}
    pears
3   $ echo $foo
    grapes
    $
说明
1. 将变量foo的值设置为grapes。
2. 专用修饰符:=将检查变量name是否已被设置。如果已经被设置过,就用pears暂时替换foo。否则,返回空。
3. 变量foo的值还是原来的值。
范例13-63
(基于默认值创建错误信息)
1   $ echo ${namex:?"namex is undefined"}
    namex: namex is undefined
2   $ echo ${y?}
    y: parameter null or not set
说明  
1. 修饰赋:?检查变量是否已被设置。如果尚未设置该变量,就把问号右边的信息打印在标准错误输出上。如果此时是在执行脚本,就退出脚本。
2. 如果问号后面没有提供报错信息,shell就向标准错误输出发送默认的消息。
范例13-64
(创建子串 20)
1   $ var=notebook
2   $ echo ${var:0:4}
    note
3   $ echo ${var:4:4}
    book
4   $ echo ${var:0:2}
    no
说明
1. 给变量赋值notebook。
2. var的子串从偏移0(notebook中的n)开始,长度为4个字符,在e处结束。
3. var的子串从偏移4(notebook中的b)开始,长度为4个字符,在k处结束。
4. var的子串从偏移0(notebook中的n)开始,长度为2个字符,在o处结束。
13.10.9  子串的变量扩展
模式匹配变量用来在串首或串尾截掉串的某一特定部分。这些操作符最常见的用法是从路径头或尾删除路径名元素。如表13-19所示。
表13-19  变量扩展子串 
表  达  式
 功    能
 
${变量%模式}
 将变量值的尾部与模式进行最小匹配,并将匹配到的部分删除
 
${变量%%模式}
 将变量值的尾部与模式进行最大匹配,并将匹配到的部分删除
 
${变量#模式}
 将变量值的头部与模式进行最小匹配,并将匹配到的部分删除
 
${变量##模式}
 将变量值的头部与模式进行最大匹配,并将匹配到的部分删除
 
${#变量}
 替换为变量中的字符个数。如果是*或@,长度则是位置参量的个数
 


范例13-65
1   $ pathname="/usr/bin/local/bin"
2   $ echo ${pathname%/bin*}
    /usr/bin/local
说明
1. 给局部变量pathname赋值/usr/bin/local/bin。
2. %删除路径名尾部包含模式/bin,后跟零个或多个字符的最小部分。即删除/bin。
范例13-66
1   $ pathname="usr/bin/local/bin"
2   $ echo ${pathname%%/bin*}
    /usr
说明
1. 给局部变量pathname赋值/usr/bin/local/bin。
2. %%删除路径名尾部包含模式/bin,后跟零个或多个字符的最大部分。即删除/bin/local/bin。
范例13-67
1   $ pathname=/home/lilliput/jake/.bashrc
2   $ echo ${pathname#/home}
    /lilliput/jake/.bashrc
说明
1. 给局部变量pathname赋值/home/liliput/jake/.bashrc。
2. #删除路径名头部包含模式/home的最小部分。路径变量开头的/home被删除。
范例13-68
1   $ pathname=/home/lilliput/jake/.bashrc
2   $ echo ${pathname##*/}
    .bashrc
说明
1. 给局部变量pathname赋值/home/liliput/jake/.bashrc。
2. ##删除路径名的头部包含零个或多个字符,直到并包括最后一个斜杠的最大部分。即从路径变量中删除/home/liliput/jake/。
范例13-69
1   $ name="Ebenezer Scrooge"
2   $ echo  ${#name}
    16
说明
1. 给变量name赋值Ebenezer Scrooge。
2. ${#variable}语法显示赋给变量name的字符串中字符的个数。字符串Ebenezer Scrooge中有16个字符。
13.10.10  位置参量
这组专用内置变量常常被称为位置参量,通常被shell脚本用来从命令行接收参数,或者被函数用来保存传给它的参数。这组变量之所以被称为位置参量,是因为引用它们要用到1、2、3等数字,这些数字分别代表它们在参数列表中的相应位置。请参见表13-20。
表13-20  位置参量
表  达  式
 功    能
 
$0
 指代当前shell脚本的名称
 
$1-$9
 代表第1个到第9个位置参量
 
${10}
 第10个位置参量
 
$#
 其值为位置参量的个数
 
$*
 其值为所有的位置参量
 
$@
 除了被双引号引用的情况,含义与$*相同
 
"$*"
 其值为"$1 $2 $3"
 
"$@"
 其值为"$1" "$2" "$3"
 


shell脚本名存在变量$0中。位置参量可以用set命令来设置,重置和复位。
范例13-70
1   $ set punky tommy bert jody
    $ echo $*            # Prints all the positional parameters
    punky tommy bert jody
2   $ echo $1           # Prints the first position
    punky
3   $ echo $2 $3       # Prints the second and third position
    tommy bert
4   $ echo $#           # Prints the total number of positional parameters
    4
5   $ set a b c d e f g h i j k l m
    $ print $10         # Prints the first positional parameter followed by a 0
    a0
    $ echo ${10} ${11} # Prints the 10th and 11th positions
    j k
6   $ echo $#
    13
7   $ echo $*
    a b c d e f g h i j k l m
8   $ set file1 file2 file3
    $ echo /$$#
    $3
9   $ eval echo /$$#
    file3
10  $ set --            # Unsets all positional parameters
  说明
1. set命令给位置参量赋值。专用变量$*包含所有的位置参量。
2. 显示第1个位置参量的值,punky。
3. 显示第2和第3个位置参量的值,tommy和bert。
4. 专用变量$#的值是当前已设置的位置参量的个数。
5. set命令复位所有的位置参量。原来的位置参量集被清除。要打印9以上的任意位置参量,就要用花括号把两个数字括起来。否则,就打印第一个位置参量的值,后跟另一个数。
6. 位置参量个数现在是13。
7. 显示所有位置参量的值。
8. 美元符被转义,$#是参数个数。echo命令显示$3,一个美元符号后跟位置参量的个数。
9. 执行命令之前,eval命令对命令行进行第二次解析。第一次由shell解析,将输出$3。第二次由eval解析,显示$3的值,即file3。
10. 带--选项的set命令清除或复位所有的位置参量。
13.10.11  其他特殊变量
shell有一些由单个字符组成的特殊变量。在字符前面加上美元符就能访问变量中保存的值。如表13-21所示。
表13-21  特殊变量
变    量
 含    义
 
$
 当前shell的PID
 
-
 当前的sh选项设置              
 
?
 已执行的上一条命令的退出值
 
!
 最后一个进入后台的作业的PID
 


范例13-71
1   $ echo The pid of this shell is $$
    The pid of this shell is 4725
2   $ echo The options for this shell are $–
    The options for this shell are imh
3   $ grep dodo /etc/passwd
    $ echo $?
    1
4   $ sleep 25&
    4736
    $ echo $!
    4736
说明
1. 变量$保存这个进程的PID值。
2. 变量–列出当前这个交互式bash shell的所有选项。
3. grep命令在/etc/passwd文件中查找字符串dodo。变量?保存了上一条被执行的命令的退出状态。由于grep返回的值是1,因此可以假定grep的查找失败了。退出状态0代表成功退出。
4. 变量!保存上一条被放入后台的命令的PID号。sleep命令后面的&把命令发到后台。
原创粉丝点击