SHELL十三问之五:var=value?export 前后差在哪?

这次让我们暂时丢开command line,先来了解一下bash变量(variable)...
?d ]0[-eL9V"n1
;W�E r%l.U#z3i&D1
所谓的变量,就是就是利用一个特定的"名称"(name)来存取一段可以变化的""(value)BSD爱好者乐园'lt0` c@)R#u
BSD爱好者乐园#e0LR%N3uV,{p
*设定(set)*
W*/B'x+M�F5y6D d1
bash中,你可以用"="来设定或重新定义变量的内容:BSD爱好者乐园#J8E7ot%AFBp,`,J9F H6Mf
        name=value
6YK$u!|m1
在设定变量的时侯,得遵守如下规则:
-S9U Id-_x(OJy1        *
等号左右两边不能使用区隔符号(IFS),也应避免使用shell的保留字符(meta charactor)BSD爱好者乐园w2F"R%S Q#},M[x|q
        *
变量名称不能使用$符号。
%Qp)}j$NLm1        *
变量名称的第一个字母不能是数字(number)
"r0pQdXu@%H x*L1        *
变量名称长度不可超过256个字母。BSD爱好者乐园 C IV7Hle
        *
变量名称及变量值之大小写是有区别的(case sensitive)BSD爱好者乐园mWj3P5N m`Jy`

#bZu7Idy:y.u1
如下是一些变量设定时常见的错误:BSD爱好者乐园A2[otf L
        A= B       
:不能有IFS
3@U(I_l(S1        1A=B       
:不能以数字开头BSD爱好者乐园F+R+[i"})Y]"SUaJ%s
        $A=B       
:名称不能有$
sH$^:o'q N ^9s-U1        a=B       
:这跟a=b是不同的
yA�MR f1
如下则是可以接受的设定:
GkT8~3E0Nko/@"V,ds1        A=" B"       
IFS被关闭了(请参考前面的quoting章节)BSD爱好者乐园'p)[#@!q'U.q
        A1=B       
:并非以数字开头
1O3O6N ?H1?V@ g1t(`0G1        A=$B       
$可用在变量值内
f bWVk0c&OP(_/Y9m1        This_Is_A_Long_Name=b       
:可用_连接较长的名称或值,且大小写有别。BSD爱好者乐园tdde t&D

-_ t-`6m?P1Jr1
*变量替换(substitution)*
m/bf"mRW2| H1z1
Shell之所以强大,其中的一个因素是它可以在命令行中对变量作替换(substitution)处理。BSD爱好者乐园RMJan6b�w9I�o
在命令行中使用者可以使用$符号加上变量名称(除了在用=号定义变量名称之外)BSD爱好者乐园`9om PV;f
将变量值给替换出来,然后再重新组建命令行。
7sJAoKqD#CPY1
比方:

!/(F ^OX Ppf~5@1

        $ A=ls
h6P1FC%]1        $ B=laBSD爱好者乐园7B@EP2Z
        $ C=/tmpBSD爱好者乐园F*s3i%P|%To ?
        $ $A -$B $C
BSD爱好者乐园C{/A$W-h@

(注意:以上命令行的第一个$shell prompt,并不在命令行之内。)BSD爱好者乐园 FS+{V�RefKI}
必需强调的是,我们所提的变量替换,只发生在command line上面。(是的,让我们再回到command line吧﹗)
A6N5e2eQ4H'OR^1
仔细分析最后那行command line,不难发现在被执行之前(在输入CR字符之前)BSD爱好者乐园:[@:q9y/&^%b!M*P
$
符号会对每一个变量作替换处理(将变量值替换出来再重组命令行),最后会得出如下命令行:

)|'V{5K|$|1

        ls -la /tmpBSD爱好者乐园 }z3[l3~1p$?(y3]:E

还记得第二章我请大家"务必理解"的那两句吗?若你忘了,那我这里再重贴一遍:BSD爱好者乐园+AR�yc {jw4Vy

若从技术细节来看,shell会依据IFS(Internal Field Seperator)command line所输入的文字给拆解为"字段"(word)BSD爱好者乐园u8i }-_'D nm$iS
然后再针对特殊字符(meta)先作处理,最后再重组整行command line

n)y{]]*i1

这里的$就是command line中最经典的meta之一了,就是作变量替换的﹗
tav4KQ1
在日常的shell操作中,我们常会使用echo命令来查看特定变量的值,例如:BSD爱好者乐园6[V~`W6QUH

        $ echo $A -$B $CBSD爱好者乐园%Liqj'R

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

RWWWu8n._ D1

        ls -la /tmp

d,ViB'Fp3y1

这是由于echo命令在执行时,会先将$A(ls)$B(la)、跟$C(/tmp)给替换出来的结果。
Tc c&nVa1
C0^W4_Y0]:w.~5y!t _1
利用shell对变量的替换处理能力,我们在设定变量时就更为灵活了:
Hb8B*lU6J3~2L1        A=BBSD爱好者乐园j Mp(p5FeE6r0p
        B=$ABSD爱好者乐园)nKNGsw._
这样,B的变量值就可继承A变量"当时"的变量值了。
N:dP| p g1
不过,不要以"数学罗辑"来套用变量的设定,比方说:BSD爱好者乐园/fq3~Y;p3GI |hxdW
        A=B
?]4uL;v c/l7F1        B=C
"C*n:M"Q#O�{"?Q(id-[E1
这样并不会让A的变量值变成C
L./%?.d(B1
上面是单纯定义了两个不同名称的变量:A  B,它们的值分别是B  C。再如:BSD爱好者乐园�r;qDa!{&Fnp2flC
        A=BBSD爱好者乐园F-AA*U^'@%M+` s
        B=$ABSD爱好者乐园�/9t!oB}@wmRyO
        A=C
X H*Q/U |q tl T1
同样也不会让B的值换成CBSD爱好者乐园.y9Y'v7EHhvB
 
2h#dsO-{"@9O9PDc*z1
若变量被重复定义的话,则原有旧值将被新值所取代。(这不正是"可变的量"吗?  ^_^)BSD爱好者乐园g4{cr%Ap
当我们在设定变量的时侯,请记着这点:BSD爱好者乐园1x KO ~)n
        *用一个名称储存一个数值
3I.x�?I�Z�r1
仅此而已。BSD爱好者乐园0R,t-F:P9C/m-Q m
BSD爱好者乐园 U$B[(Z,qd%/5s
此外,我们也可利用命令行的变量替换能力来"扩充"(append)变量值:
Ble"E^~g1        A=B:C:D
:I&L3s:bqqY2d2l1        A=$A:E
[ Mqri:u D%eIM1
这样,第一行我们设定A的值为"B:C:D",然后,第二行再将值扩充为"A:B:C:E"BSD爱好者乐园%a@Y(@9a @
BSD爱好者乐园_;a1N { Wd
上面的扩充范例,我们使用区隔符号( : )来达到扩充目的,
MM1W`k*@:G&Sdpn1
要是没有区隔符号的话,如下是有问题的:
]n P;D6A5Cb;B1        A=BCDBSD爱好者乐园6tvH7q-A9a&qD|N(DG
        A=$AEBSD爱好者乐园 S4Z pP`$w
因为第二次是将A的值继承$AE的提换结果,而非$A再加EBSD爱好者乐园%yD$np']V TP:/
要解决此问题,我们可用更严谨的替换处理:BSD爱好者乐园'z9[PO`0hI
        A=BCD
:d!jO'bb /"T1        A=${A}E
2u1at'H-Pc1
上例中,我们使用{}将变量名称的范围给明确定义出来,BSD爱好者乐园1I9UrauK5[}I�Q
如此一来,我们就可以将A的变量值从BCD给扩充为BCDEBSD爱好者乐园.@4Ie�|3{'W[ G_r

SD+Tz2w1(
提示:关于${name}事实上还可做到更多的变量处理能力,这些均属于比较进阶的变量处理,现阶段暂时不介绍了,请大家自行参考数据。如CU的贴子:BSD爱好者乐园[s6]#l7D-RiBY
http://www.chinaunix.net/forum/viewtopic.php?t=201843)BSD爱好者乐园 Mi*w)Yd `T

u4r SqM/Ab#X1
* export *BSD爱好者乐园 s;o7J$y8WU:RRP

G7C[7Y` zAQ O$UT1
严格来说,我们在当前shell中所定义的变量,均属于"本地变量"(local variable)
8Gc2_2c U-E1
只有经过export命令的"输出"处理,才能成为环境变量(environment variable)

4aW6IE)M1

        $ A=BBSD爱好者乐园 UH3X x:@2GR}
        $ export A
BSD爱好者乐园%}�?#u7t#U2L)P

或:

Q G:k(kN4T;z'z1

        $ export A=B

|X z ]/c+L(]i3n1

经过export输出处理之后,变量A就能成为一个环境变量供其后的命令使用。
GO1t(v8}f9`1
在使用export  的时侯,请别忘记shell在命令行对变量的"替换"(substitution)处理,BSD爱好者乐园4kqNL{*h&LJ#m
比方说:

^ss ]8l1

        $ A=B
o�T%{m*p{1        $ B=CBSD爱好者乐园{f9z;Ngh8C-Y3W{
        $ export $A

M#`&}6B1G Gg^$Wr1

上面的命令并未将A输出为环境变量,而是将B作输出,BSD爱好者乐园E#K3I4r6c5h
这是因为在这个命令行中,$A会首先被提换出B然后再"塞回"export的参数。
:IZ6s�B Y`A"~1
0/;|{(bg wb"^&^4R1
要理解这个export,事实上需要从process的角度来理解才能透彻。
6n/nJ2n1
我将于下一章为大家说明process的观念,敬请留意。BSD爱好者乐园K6/ o @6Rh{
BSD爱好者乐园6f0a!Hmhx/
*取消变量*BSD爱好者乐园Uaz_P_DjJ

NYy e&r0[1
要取消一个变量,在bash中可使用unset命令来处理:

7{,qZ oS&t)|0C ?5M1

        unset A

x1~aW{+v)b1

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

@ {FZfqR,j1

        $ A=BBSD爱好者乐园1W:T2teDQ3V
        $ B=C
@i&x1W])f ~~cNb1        $ unset $A

u T!Dwa^C P1K1

事实上所取消的变量是B而不是A
T.Y ^5Z _M-v3m1
MB0vjx*B2K�D5Y a1
此外,变量一旦经过unset取消之后,其结果是将整个变量拿掉,而不仅是取消其变量值。BSD爱好者乐园+z H/7b1HE
如下两行其实是很不一样的:BSD爱好者乐园 ptJhd8y0j7G

        $ A=
8d"eC/m9e+Y ]1        $ unset A

o?HUG,]1

第一行只是将变量A设定为"空值"(null  value),但第二行则让变量A不在存在。
S"r[#xTD1
虽然用眼睛来看,这两种变量状态在如下命令结果中都是一样的:BSD爱好者乐园2yL&Mw�vT }-WW

        $ A=BSD爱好者乐园+MG*F Us)j5k
        $ echo $ABSD爱好者乐园i%y~#io$A n-ci-I
BSD爱好者乐园K*pS%[J
        $ unset ABSD爱好者乐园m2/nV ^
        $ echo $A
BSD爱好者乐园K.M4V@q"P�{P[

7O9z / o,OmuT[1[版权声

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值