-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbash-shell-tutorial-variables-scope.t2t
More file actions
154 lines (118 loc) · 5.2 KB
/
Copy pathbash-shell-tutorial-variables-scope.t2t
File metadata and controls
154 lines (118 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
Bash-Shell-Tutorial
<TITLE>
Cai Yuanqing <ckjacket@gmail.com>
%!includeconf: config.t2t
%!postproc: '(?i)(</title>)' ' Variables-Scope \1'
%!postproc: '(?i)(<body)' '\1 id="variables-scope"'
%%!include: menu.t2t
%%% Some post processing filter magic (search & replace)
% meta: keywords
%!postproc: (</HEAD>) <meta name="keywords" content="txt2tags, convert, conversion, online, text, HTML, XHTML, SGML, LaTeX, Lout, Man page, Wikipedia, Google Code Wiki, DokuWiki, MoinMoin, MagicPoint, PageMaker, Python, free, tool, markup, Linux, Mac, Windows, GPL">\n\1
% meta: description
%!postproc: (</HEAD>) <meta name="description" content="txt2tags - Convert plain text to HTML, XHTML, SGML, LaTeX, DocBook, Lout, Man page, Creole, Wikipedia, Google Code Wiki, DokuWiki, PmWiki, MoinMoin, MagicPoint, PageMaker, AsciiDoc and ASCII Art!">\n\1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
= 变量作用域 =
在Bourne Shell中,变量不需要像在C中一定要先声明。但是如果你试图读取一个没有声明过得变量,读到的会是空字符串。这可能会造成难以发现的问题,因为读取未声明的变量并不会有任何的错误或警告。例如你给一个变量赋值 //MY_CORRECT_VAR=hello//,然后//echo $MY_CORECT_VAR//,由于拼写错误,想要输出的是个未声明变量,因此什么输出也没有。
这里有一个命令//export//用于设置变量的作用域。为了明确的知道你所声明的变量如何被使用,接下来我们必须先明白如何使用//export//.
创建一个简单的脚本,//myvar2.sh//:
====================================================
__myvar2.sh__
```
#!/bin/sh
echo "MYVAR is: $MYVAR"
MYVAR="hi there"
echo "MYVAR now is: $MY_NAME!"
```
====================================================
然后运行它:
```
$ ./myvar2.sh
MYVAR is:
MYVAR now is: hi there!
```
MYVAR最初并没有被声明和赋值,所以第一次输出时,它是空的。然后我们给它赋值,便可以输出想要的结果了。
那如果我们先在shell中给他赋值,再输出能得到我们想要的结果吗?
```
$ MYVAR=hello
$ ./myvar2.sh
MYVAR is:
MYVAR now is: hi there!
```
看来仍然没有起作用!那发生了什么呢?
当你从当前的shell中执行//./myvar2.sh//时,事实上是在一个新的shell进程中运行的,这就是我们最初讨论到的关于//#!/bin/sh//的意义。
我们对MYVAR的赋值是在当前shell中执行的,因此在新的shell中这个变量并没有被继承下去,//exprot//的作用便是让一个变量可以从当前shell继承到派生出的进程中。
例如:
```
export MYVAR=hello
$ ./myvar2.sh
MYVAR is: hello
MYVAR now is: hi there!
```
现在可以看到MYVAR的赋值起作用了。从上面我们看到在//myvar2.sh//中我们对MYVAR的值进行了修改,但是它无法将修改的值传回给当前shell来修改MYVAR的值:
```
$ echo $MYVAR
hello
```
一旦shell脚本退出,那么它的变量,资源都将被释放,所以在当前shell中,MYVAR仍然保持它原本的值//hello//.
为了能让脚本中的修改也能影响当前的shell,我们必须//source//这个脚本,它的实际效果是将脚本在当前shell中执行,而不是新建一个进程。
我们可以通过"."命令来//source//一个脚本:
```
MYVAR=hello
$ echo $MYVAR
hello
$ . myvar2.sh
MYVAR is: hello
MYVAR now is: hi there!
$ echo $MYVAR
hi there
```
这样就实现了对当前shell中变量的修改,这也正是我们系统中的//.profile//或者//.bash_profile//等环境变量脚本工作的方式。
另外,这种情况下,可以直接对变量赋值,不需要在//export//.
==================================================
```
#!/bin/sh
echo "What's your name?"
read URNAME
echo "Hello $URNAME"
echo "I will create your profile: $URNAME_file"
touch $URNAME_file
```
==================================================
考虑下上面这个脚本,例如你输入名字"nehe"到//URNAME//中,那么最终会有一个叫做nehe_file的文件被创建吗?
```
$ ./nehe_file.sh
What's your name?
nehe
Hello nehe
I will create your profile:
touch: missing file operand
Try `touch --help' for more information.
```
看来不是这样。这是因为shell不知道你的变量在哪里结束,除非你有一个叫做//URNAME_file//的变量,那我们怎么来定义一个已知变量和字符串的结合呢?
答案是将变量用花括号括起来:-D
==================================================
__nehe_file.sh__
```
#!/bin/sh
echo "What's your name?"
read URNAME
echo "Hello $URNAME"
echo "I will create your profile: ${URNAME}_file"
touch ${URNAME}_file
```
```
$ ./nehe_file.sh
What's your name?
nehe
Hello nehe
I will create your profile: nehe_file
```
==================================================
现在shell就可以知道变量名是**URNAME**,后面会接上一个字符串//_file//.
新手更应该在这个地方多加谨慎,因为这种错误可能很隐蔽,也很难去跟踪排错。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%!include: footer.t2t