专注各种脚本编程
Baidu
加入收藏夹
本站内容有下面分类知识,欢迎您的到来^_^
shell相关:指令篇 基础篇 脚本欣赏 编程实例 shell问问 shell视频教程 技巧篇 水平测试 E文资料 vi编辑器 高级Bash脚本编程指南
其他:mysql perl c语言 oracle
当前位置:| 主页>shell问问>

五问:var=value?export 前后差在哪?

百度收藏 QQ搜藏

    这次让我们暂时丢开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
   还记得第二章我请大家"务必理解"的那两句吗?若你忘了,那我这里再重贴一遍:
    若从技术细节来看,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} 事实上还可做到更多的变量处理能力,这些均属于比较进阶的变量处理,现阶段暂时不介绍了,请大家自行参考资料。)
* 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
    聪明的读者(yes, you!),稍加思考的话,应该不难发现为何同样的 var=${str=expr} 在 null 与 unset 之下的不同吧?若你看不出来,那可能是如下原因之一:
a. 你太笨了
b. 不了解 var=${str=expr} 这个进阶处理
c. 对本篇说明还没来得及消化吸收
e. 我讲得不好
不知,你选哪个呢?.... ^_^

上一篇:四问:" "(双引号) 与 ' '(单引号)差在哪? 下一篇:六问:exec跟source有何差别?

power by soyo123 2007-2008