Chinaunix首页 | 论坛 | 博客
  • 博客访问: 364935
  • 博文数量: 83
  • 博客积分: 5322
  • 博客等级: 中校
  • 技术积分: 1057
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-11 11:27
个人简介

爱生活,爱阅读

文章分类

全部博文(83)

文章存档

2015年(1)

2013年(1)

2012年(80)

2011年(1)

分类: LINUX

2012-02-29 15:30:08


-------------------------------------------------------------------------------------------------------------

------------------------------收集于网络:网中人---shell 十三问》---------------------------

-------------------------------------------------------------------------------------------------------------

 

这次让我们暂时丢开 command line ,先来了解一下 bash 变量(variable)...

 

所谓的变量,就是就是利用一个特定的"名称"(name)来存取一段可以变化的""(value)

 

*设定(set)*

bash 中,你可以用 "=" 来设定或重新定义变量的内容:

        name=value

在设定变量的时侯,得遵守如下规则:

        * 等号左右两边不能使用区隔符号(IFS),也应避免使用 shell 的保留字符(meta charactor)

        * 变量名称不能使用 $ 符号。

        * 变量名称的第一个字母不能是数字(number)

        * 变量名称长度不可超过 256 个字母。

        * 变量名称及变量值之大小写是有区别的(case sensitive)

 

如下是一些变量设定时常见的错误:

        A= B       :不能有 IFS

        1A=B       :不能以数字开头

        $A=B       :名称不能有 $

        a=B        :这跟 a=b 是不同的

如下则是可以接受的设定:

        A=" B"      IFS 被关闭了 (请参考前面的 quoting 章节)

        A1=B       :并非以数字开头

        A=$B       $ 可用在变量值内

        This_Is_A_Long_Name=b        :可用 _ 连接较长的名称或值,且大小写有别。

 

*变量替换(substitution)*

Shell 之所以强大,其中的一个因素是它可以在命令行中对变量作替换(substitution)处理。在命令行中使用者可以使用 $ 符号加上变量名称(除了在用 = 号定义变量名称之外)将变量值给替换出来,然后再重新组建命令行。
 
    例如:

$ A=ls

$ B=la

$ C=/tmp

$ $A -$B $C

(注意:以上命令行的第一个 $ shell prompt,并不在命令行之内。)

    必需强调的是,我们所提的变量替换,只发生在 command line 上面。(是的,让我们再回到 command line 吧﹗)。仔细分析最后那行 command line ,不难发现在被执行之前(在输入 CR 字符之前)$ 符号会对每一个变量作替换处理(将变量值替换出来再重组命令行),最后会得出如下命令行:

 

$ls -la /tmp

    还记得第二章我请大家"务必理解"的那两句吗?若你忘了,那我这里再重贴一遍:

QUOTE:

若从技术细节来看,shell 会依据 IFS(Internal Field Seperator) command line 所输入的文字给拆解为"字段"(word)

然后,再针对特殊字符(meta)先作处理,最后再重组整行 command line 这里的 $ 就是 command line 中最经典的 meta 之一了,就是作变量替换的﹗

在日常的 shell 操作中,我们常会使用 echo 命令来查看特定变量的值,例如:

 

$ echo $A -$B $C

我们已学过,echo 命令只单纯将其 argument 送至"标准输出"(STDOUT,通常是我们的荧幕) 所以上面的命令会在荧幕上得到如下结果:

$ls -la /tmp

这是由于 echo 命令在执行时,会先将 $A(ls)$B(la)、跟 $C(/tmp) 给替换出来的结果。

利用 shell 对变量的替换处理能力,我们在设定变量时就更为灵活了:

        A=B

        B=$A

    这样,B 的变量值就可继承 A 变量"当时"的变量值了。

    不过,不要以"数学罗辑"来套用变量的设定,比方说:

        A=B

        B=C

    这样并不会让 A 的变量值变成C
    再如:

        A=B

        B=$A

        A=C

    同样也不会让 B 的值换成C

上面是单纯定义了两个不同名称的变量:A   B ,它们的值分别是 B  C

若变量被重复定义的话,则原有旧值将被新值所取代。(这不正是"可变的量"吗?)

当我们在设定变量的时侯,请记着这点:

        * 用一个名称储存一个数值

仅此而已!

 

    此外,我们也可利用命令行的变量替换能力来"扩充"(append)变量值:

        A=B:C:D

        A=$A:E

这样,第一行我们设定 A 的值为 "B:C:D",然后,第二行再将值扩充为"A:B:C:E"

   上面的扩充范例,我们使用区隔符号(:)来达到扩充目的,要是没有区隔符号的话,如下是有问题的:

        A=BCD

        A=$AE

因为第二次是将 A 的值继承 $AE 的提换结果,而非 $A 再加 E ﹗要解决此问题,我们可用更严谨的替换处理:

        A=BCD

        A=${A}E

上例中,我们使用 {} 将变量名称的范围给明确定义出来,如此一来,我们就可以将 A 的变量值从 BCD 给扩充为 BCDE

 

(提示:关于 ${name},事实上还可做到更多的变量处理能力。这些均属于比较进阶的变量处理,现阶段暂时不介绍了,请大家自行参考数据。如 CU 的贴子:

[url]l])

 

* export *

严格来说,我们在当前 shell 中所定义的变量,均属于"本地变量"(local variable)只有经过 export 命令的"输出"处理,才能成为环境变量(environment variable)

$ A=B

$ export A

或:

$ export A=B

经过 export 输出处理之后,变量 A 就能成为一个环境变量供其后的命令使用。在使用 export  的时侯,请别忘记 shell 在命令行对变量的"替换"(substitution)处理,比方说:

$ A=B

$ B=C

$ export $A

上面的命令并未将 A 输出为环境变量,而是将 B 作输出,这是因为在这个命令行中,$A 会首先被提换出 B 然后再"塞回" export 的参数。

 

要理解这个 export ,事实上需要从 process 的角度来理解才能透彻。我将于下一章为大家说明 process 的观念,敬请留意。

 

*取消变量*

 

要取消一个变量,在 bash 中可使用 unset 命令来处理:

$unset A

export 一样,unset 命令行也同样会作变量替换(这其实就是 shell 的功能之一),因此:

$ A=B

$ B=C

$ unset $A

     事实上所取消的变量是 B 而不是 A

此外,变量一旦经过 unset 取消之后,其结果是将整个变量拿掉,而不仅是取消其变量值。如下两行其实是很不一样的:

$ A=

$ unset A

第一行只是将变量 A 设定为"空值"(null  value),但第二行则让变量 A 不再存在。虽然用眼睛来看,这两种变量状态在如下命令结果中都是一样的:

$ A=

$ echo $A

$ unset A

$ echo $A

请务必能识别 null value unset 的本质区别,这在一些进阶的变量处理上是很严格的。比方说:

$ str=                # 设为 null

$ var=${str=expr}        # 定义 var

$ echo $var

$ echo $str

$ unset str        # 取消

$ var=${str=expr}        # 定义 var

$ echo $var

expr

$ echo $str

expr
-----------------------------------------------------------

[admin@localhost ~]$ str= 

[admin@localhost ~]$ var=${str=expr}

[admin@localhost ~]$ echo $var


[admin@localhost ~]$ echo $str


[admin@localhost ~]$ unset str

[admin@localhost ~]$ var=${str=expr}

[admin@localhost ~]$ echo $var      

expr

[admin@localhost ~]$ echo $str      

expr

[admin@localhost ~]$ 

-----------------------------------------------------------

聪明的读者(yes, you!),稍加思考的话,应该不难发现为何同样的 var=${str=expr} null unset 之下的不同吧?

若你看不出来,那可能是如下原因之一:

a. 你太笨了

b. 不了解  var=${str=expr} 这个进阶处理

c. 对本篇说明还没来得及消化吸收

e. 我讲得不好

不知,你选哪个呢 ?

--------------------------------------------------------------
另:关于${},参见:

var=${str=expr} :

首先,var=$str 這個大家都可理解吧。
而接下來的思考方向是,究竟 $str 這個變量是如下哪一種情況呢:
1) unset
2) null
3) not null

1) 假如是 unset ,那麼 var=${str=expr} 的結果將是:
var=expr
str=expr

2) 假如是 null ,那 var=${str=expr} 的結果是:
var=
str=

3) 假如是 not null (比方為 xyz ),那 var=${str=expr} 之結果是:
var=xyz
str=xyz

阅读(1129) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~