Skip to content

Commit c964f38

Browse files
committed
docs: edit function
1 parent 60219a8 commit c964f38

4 files changed

Lines changed: 228 additions & 188 deletions

File tree

docs/archives/function.md

Lines changed: 0 additions & 97 deletions
This file was deleted.

docs/function.md

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
# Bash 函数
2+
3+
## 简介
4+
5+
函数(function)是可以重复使用的代码片段,有利于代码的复用。它与别名(alias)的区别是,别名只适合封装简单的单个命令,函数则可以封装复杂的多行命令。
6+
7+
函数总是在当前 Shell 执行,这是跟脚本的一个重大区别。如果函数与脚本同名,函数会优先执行。但是,函数的优先级不如别名,即如果函数与别名同名,那么别名优先执行。
8+
9+
Bash 函数定义的语法有两种。
10+
11+
```bash
12+
# 第一种
13+
fn() {
14+
# codes
15+
}
16+
17+
# 第二种
18+
function fn() {
19+
# codes
20+
}
21+
```
22+
23+
上面代码中,`fn`是自定义的函数名,函数代码就写在大括号之中。这两种定义函数的写法是等价的。
24+
25+
下面是一个简单函数的例子。
26+
27+
```bash
28+
hello() {
29+
echo "Hello $1";
30+
}
31+
```
32+
33+
上面代码中,函数体里面的`$1`表示函数调用时的第一个参数。
34+
35+
调用时,可以直接执行函数名,参数跟着函数名后面。
36+
37+
```bash
38+
$ hello world
39+
hello world
40+
```
41+
42+
下面是一个多行函数的例子,显示当前日期时间。
43+
44+
```bash
45+
today() {
46+
echo -n "Today's date is: "
47+
date +"%A, %B %-d, %Y"
48+
}
49+
```
50+
51+
查看当前 Shell 已经定义的所有函数,可以使用`declare`命令。
52+
53+
```bash
54+
$ declare -f
55+
```
56+
57+
上面的`declare`命令不仅会输出函数名,还会输出所有定义。输出顺序是按照函数名的字母表顺序。由于会输出很多内容,最好通过管道命令配合`more``less`使用。
58+
59+
`declare`命令还支持查看单个函数的定义。
60+
61+
```bash
62+
$ declare -f functionName
63+
```
64+
65+
`declare -F`可以输出所有已经定义的函数名,不含函数体。
66+
67+
```bash
68+
$ declare -F
69+
```
70+
71+
删除一个函数,可以使用`unset`命令。
72+
73+
```bash
74+
unset -f functionName
75+
```
76+
77+
## 参数变量
78+
79+
函数体内可以使用参数变量,获取外部参数。函数的参数变量,与脚本参数变量是一致的。
80+
81+
- `$1`~`$9`:函数的第一个到第9个的参数。
82+
- `$0`:函数所在的脚本名。
83+
- `$#`:函数的参数总数。
84+
- `$a`:函数的全部参数,参数之间使用空格分隔。
85+
- `$*`:函数的全部参数,参数之间使用变量`$IFS`值的第一个字符分隔,默认为空格,但是可以自定义。
86+
87+
如果函数的参数多于9个,那么第10个参数可以用`${10}`的形式引用,以此类推。
88+
89+
下面是一个示例脚本`test.sh`
90+
91+
```bash
92+
# 脚本文件 test.sh
93+
function alice {
94+
echo "alice: $@"
95+
echo "$0: $1 $2 $3 $4"
96+
echo "$# arguments"
97+
98+
}
99+
100+
alice in wonderland
101+
```
102+
103+
运行该脚本,结果如下。
104+
105+
```bash
106+
$ bash test.sh
107+
alice: in wonderland
108+
test.sh: in wonderland
109+
2 arguments
110+
```
111+
112+
上面这个例子中,由于函数`alice`只有第一个和第二个参数,所以第三个和第四个参数为空。
113+
114+
下面是一个日志函数的例子。
115+
116+
```bash
117+
function log_msg {
118+
echo "[`date '+ %F %T'` ]: $@"
119+
}
120+
```
121+
122+
使用方法如下。
123+
124+
```bash
125+
$ log_msg "This is sample log message"
126+
[ 2018-08-16 19:56:34 ]: This is sample log message
127+
```
128+
129+
## 返回值
130+
131+
`return`命令用于从函数返回一个值。
132+
133+
```bash
134+
function func_return_value {
135+
return 10
136+
}
137+
```
138+
139+
函数将返回值返回给调用者。如果命令行直接执行函数,下一个命令可以用`$?`拿到返回值。
140+
141+
```bash
142+
$ func_return_value
143+
$ echo "Value returned by function is: $?"
144+
Value returned by function is: 10
145+
```
146+
147+
## 全局变量和局部变量
148+
149+
Bash 函数体内直接声明的变量,属于全局变量,整个脚本都可以读取。这一点需要特别小心。
150+
151+
```bash
152+
# 脚本 test.sh
153+
fn () {
154+
foo=1
155+
echo "fn: foo = $foo"
156+
}
157+
158+
fn
159+
echo "global: foo = $foo"
160+
```
161+
162+
上面脚本的运行结果如下。
163+
164+
```bash
165+
$ bash test.sh
166+
fn: foo = 1
167+
global: foo = 1
168+
```
169+
170+
上面例子中,变量`$foo`是在函数`fn`内部声明的,函数体外也可以读取。
171+
172+
函数体内不仅可以声明全局变量,还可以修改全局变量。
173+
174+
```bash
175+
foo=1
176+
177+
fn () {
178+
foo=2
179+
}
180+
181+
echo $foo
182+
```
183+
184+
上面代码执行后,输出的变量`$foo`值为2。
185+
186+
函数里面可以用`local`命令声明局部变量。
187+
188+
```bash
189+
# 脚本 test.sh
190+
fn () {
191+
local foo
192+
foo=1
193+
echo "fn: foo = $foo"
194+
}
195+
196+
fn
197+
echo "global: foo = $foo"
198+
```
199+
200+
上面脚本的运行结果如下。
201+
202+
```bash
203+
$ bash test.sh
204+
fn: foo = 1
205+
global: foo =
206+
```
207+
208+
上面例子中,`local`命令声明的`foo`变量,只在函数体内有效,函数体外没有定义。
209+
210+
## 参考链接
211+
212+
- [How to define and use functions in Linux Shell Script](https://www.linuxtechi.com/define-use-functions-linux-shell-script/), by Pradeep Kumar

0 commit comments

Comments
 (0)