Shell语言用例

bash变量的作用域

2018-10-18  本文已影响1人  CodingCode

bash变量的作用域

bash有两类变量:全局变量和函数内变量

全局变量

定义在函数外面的函数就是全局变量。
下面例子定义和使用了一个全局变量MYVAR。

#!/bin/bash

MYVAR="aaa"

echo $MYVAR

函数内使用全局变量

#!/bin/bash

function foo() {
    echo $MYVAR
}

MYVAR="aaa"

foo

echo $MYVAR

注意:

函数内变量

函数内定义变量必须使用typeset关键字。

case 1:如果没有使用typeset关键字

那么这个变量就是一个全局变量,bash会把他定义在全局作用域了。

#!/bin/bash

function foo() {
   MYVAR="aaa"
}

echo "1="$MYVAR

foo
echo "2="$MYVAR

运行结果:

1=
2=aaa

在"1"的时候全局域MYVAR还没有定义,所以为空。
在"2"的时候全局域MYVAR已经在foo内被定义了,所以打印出"aaa"。

case 2: 使用typeset关键字

还是上面的例子,只是引用了关键字typesest。

#!/bin/bash

function foo() {
   typeset MYVAR="aaa"
}

echo "1="$MYVAR

foo
echo "2="$MYVAR

运行结果:

1=
2=

可见函数内定义的变量,并没有反应到函数外面。

一个思考,在函数外定义变量是否需要typeset,其实是不需要的,有没有typeset关键字效果一样。但是有些时候需要给变量指定类型的时候,可以使用typeset表明类型,例如浮点数,或者数组变量等。

文件域变量

熟悉C语言的人,经常会问这个问题。
回答是:bash没有文件域变量。只有上述两种。

导出变量(export)

  1. 一个变量没有导出,那么说明只在当前进程有效
  2. 一个变量如果导出,则在子进程中也可见。
  3. 函数内部变量导出,那么这个变量就不再是函数内变量了,而是一个导出变量。

case 1: 函数内导出变量

#!/bin/bash

function foo() {
   export MYVAR="aaa"
}

echo "1="$MYVAR

foo
echo "2="$MYVAR

运行结果:

1=
2=aaa

这个MYVAR已经是一个全局变量了;当然你可以试试下面这种语法:

$ cat main.sh
#!/bin/bash
function foo() {
   typeset export MYVAR1="aaa"
   export typeset MYVAR2="bbb"
}

foo

echo "1="$MYVAR1
echo "2="$MYVAR2

$ main.sh
1=
2=bbb

MYVAR1没有打出来;注意在实际项目中,我们一般不这么用的 :-)。

case 2: 导出变量用法

看一个例子:

#!/bin/bash

MYVAR1="111"
export MYVAR2="222"

function foo() {
   MYVAR3="333"
   export MYVAR4="444"
   typeset MYVAR5="555"
}

foo

echo "m1="$MYVAR1
echo "m2="$MYVAR2
echo "m3="$MYVAR3
echo "m4="$MYVAR4
echo "m5="$MYVAR5

./sub.sh

看sub.sh

#!/bin/bash

echo "s1="$MYVAR1
echo "s2="$MYVAR2
echo "s3="$MYVAR3
echo "s4="$MYVAR4
echo "s5="$MYVAR5

运行结果:

m1=111
m2=222
m3=333
m4=444
m5=
s1=
s2=222
s3=
s4=444
s5=

我们看到在main.sh里面除了VAR5(函数内typeset定义)其他都是可见的,而在sub.sh里面只有VAR2和VAR4可见,因为它两在main.sh里面导出(export)了。

当在bash里面调用另一个脚本的时候,实际上是发起另一个进程,和调用者不在一个进程空间里面。如果非要求在同一个进程空间里面,可以使用点号(.),或者source语法。
再运行上面的例子,使用source sub.sh

#!/bin/bash

MYVAR1="111"
export MYVAR2="222"

function foo() {
   MYVAR3="333"
   export MYVAR4="444"
   typeset MYVAR5="555"
}

foo

echo "m1="$MYVAR1
echo "m2="$MYVAR2
echo "m3="$MYVAR3
echo "m4="$MYVAR4
echo "m5="$MYVAR5

source ./sub.sh

这次运行的结果是:

m1=111
m2=222
m3=333
m4=444
m5=
s1=111
s2=222
s3=333
s4=444
s5=

sub.sh的结果和main.sh的结果一模一样,因为sub.sh和main.sh在同一个进程空间里面了。

上一篇下一篇

猜你喜欢

热点阅读