Skip to content

Commit f501e8a

Browse files
committed
docs: edit mktemp
1 parent 4d42908 commit f501e8a

6 files changed

Lines changed: 105 additions & 108 deletions

File tree

chapters.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
- array.md: 数组
1616
- set.md: set 命令
1717
- debug.md: 脚本除错
18+
- mktemp.md: mktemp 命令,trap 命令
1819
- startup.md: 启动环境
1920
- prompt.md: 命令提示符
20-
- mktemp.md: mktemp 命令
21-
- trap.md: trap 命令

docs/mktemp.md

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# mktemp 命令
1+
# mktemp 命令,trap 命令
22

3-
有时,Bash 脚本需要创建临时文件或临时目录。常见的做法是,自己在`/tmp`目录里面生成一个文件,这样做有很多弊端,使用`mktemp`命令是最安全的做法。
3+
Bash 脚本有时需要创建临时文件或临时目录。常见的做法是,`/tmp`目录里面创建文件或目录,这样做有很多弊端,使用`mktemp`命令是最安全的做法。
44

55
## 临时文件的安全问题
66

@@ -16,13 +16,11 @@ $ ls -l /tmp/info.txt
1616

1717
上面命令在`/tmp`目录直接创建文件,该文件默认是所有人可读的。
1818

19-
其次,如果攻击者知道临时文件的文件名,他可以创建符号链接,链接到临时文件,可能导致系统运行异常。攻击者也可能向脚本提供一些恶意数据。因此,临时文件最好使用不可预测、每次都不一样的文件名。
19+
其次,如果攻击者知道临时文件的文件名,他可以创建符号链接,链接到临时文件,可能导致系统运行异常。攻击者也可能向脚本提供一些恶意数据。因此,临时文件最好使用不可预测、每次都不一样的文件名,防止被利用
2020

2121
最后,临时文件使用完毕,应该删除。但是,脚本意外退出时,往往会忽略清理临时文件。
2222

23-
## 临时文件的最佳实践
24-
25-
脚本生成临时文件,应该遵循下面的规则。
23+
生成临时文件应该遵循下面的规则。
2624

2725
> - 创建前检查文件是否已经存在。
2826
> - 确保临时文件已成功创建。
@@ -55,7 +53,7 @@ TMPFILE=$(mktemp)
5553
echo "Our temp file is $TMPFILE"
5654
```
5755

58-
为了确保临时文件创建成功,`mktemp`命令后面最好使用 OR 运算符(`||`),指定创建失败时退出脚本
56+
为了确保临时文件创建成功,`mktemp`命令后面最好使用 OR 运算符(`||`),保证创建失败时退出脚本
5957

6058
```bash
6159
#!/bin/bash
@@ -98,7 +96,85 @@ $ mktemp -t mytemp.XXXXXXX
9896
/tmp/mytemp.yZ1HgZV
9997
```
10098

99+
## trap 命令
100+
101+
`trap`命令用来在 Bash 脚本中响应系统信号。
102+
103+
最常见的系统信号就是 SIGINT(中断),即按 Ctrl + C 所产生的信号。`trap`命令的`-l`参数,可以列出所有的系统信号。
104+
105+
```bash
106+
$ trap -l
107+
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
108+
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
109+
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
110+
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
111+
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
112+
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
113+
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
114+
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
115+
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
116+
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
117+
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
118+
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
119+
63) SIGRTMAX-1 64) SIGRTMAX
120+
```
121+
122+
`trap`的命令格式如下。
123+
124+
```bash
125+
$ trap [动作] [信号1] [信号2] ...
126+
```
127+
128+
上面代码中,“动作”是一个 Bash 命令,“信号”常用的有以下几个。
129+
130+
> - HUP:编号1,脚本与所在的终端脱离联系。
131+
> - INT:编号2,用户按下 Ctrl + C,意图让脚本中止运行。
132+
> - QUIT:编号3,用户按下 Ctrl + 斜杠,意图退出脚本。
133+
> - KILL:编号9,该信号用于杀死进程。
134+
> - TERM:编号15,这是`kill`命令发出的默认信号。
135+
> - EXIT:编号0,这不是系统信号,而是 Bash 脚本特有的信号,不管什么情况,只要退出脚本就会产生。
136+
137+
`trap`命令响应`EXIT`信号的写法如下。
138+
139+
```bash
140+
$ trap 'rm -f "$TMPFILE"' EXIT
141+
```
142+
143+
上面命令中,脚本遇到`EXIT`信号时,就会执行`rm -f "$TMPFILE"`
144+
145+
trap 命令的常见使用场景,就是在 Bash 脚本中指定退出时执行的清理命令。
146+
147+
```bash
148+
#!/bin/bash
149+
150+
trap 'rm -f "$TMPFILE"' EXIT
151+
152+
TMPFILE=$(mktemp) || exit 1
153+
ls /etc > $TMPFILE
154+
if grep -qi "kernel" $TMPFILE; then
155+
echo 'find'
156+
fi
157+
```
158+
159+
上面代码中,不管是脚本正常执行结束,还是用户按 Ctrl + C 终止,都会产生`EXIT`信号,从而触发删除临时文件。
160+
161+
注意,`trap`命令必须放在脚本的开头。否则,它上方的任何命令导致脚本退出,都不会被它捕获。
162+
163+
如果`trap`需要触发多条命令,可以封装一个 Bash 函数。
164+
165+
```bash
166+
function egress {
167+
command1
168+
command2
169+
command3
170+
}
171+
172+
trap egress EXIT
173+
```
174+
101175
## 参考链接
102176

103177
- [Working with Temporary Files and Directories in Shell Scripts](https://www.putorius.net/working-with-temporary-files.html), Steven Vona
178+
- [Using Trap to Exit Bash Scripts Cleanly](https://www.putorius.net/using-trap-to-exit-bash-scripts-cleanly.html)
179+
- [Sending and Trapping Signals](https://mywiki.wooledge.org/SignalTrap)
104180

docs/prompt.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## 环境变量 PS1
66

7-
命令提示符通常是美元符号`$`对于根用户则是`#`。这个符号是环境变量`PS1`决定的,执行下面的命令,可以看到当前命令提示符的定义。
7+
命令提示符通常是美元符号`$`对于根用户则是井号`#`。这个符号是环境变量`PS1`决定的,执行下面的命令,可以看到当前命令提示符的定义。
88

99
```bash
1010
$ echo $PS1
@@ -87,7 +87,7 @@ $ PS1="\A \h \$ "
8787
PS1='\[\033[0;31m\]<\u@\h \W>\$'
8888
```
8989

90-
但是,上面这样设置以后,用户在提示符后面输入的文本也是红色的。为了解决这个问题, 可以在结尾添加另一个特殊代码,将其后的文本恢复到原来的颜色
90+
但是,上面这样设置以后,用户在提示符后面输入的文本也是红色的。为了解决这个问题, 可以在结尾添加另一个特殊代码`\[\033[00m\]`,表示将其后的文本恢复到默认颜色
9191

9292
```bash
9393
PS1='\[\033[0;31m\]<\u@\h \W>\$\[\033[00m\]'

docs/startup.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
用户每次使用 Shell,都会开启一个与 Shell 的 Session(对话)。
66

7-
Session 有两种类型:登录 Session 和非登录 Session,也可以叫做登录 Session(login shell)和非登录 Session(non-login shell
7+
Session 有两种类型:登录 Session 和非登录 Session,也可以叫做 login shellnon-login shell。
88

99
### 登录 Session
1010

@@ -14,11 +14,11 @@ Session 有两种类型:登录 Session 和非登录 Session,也可以叫做
1414

1515
- `/etc/profile`:所有用户的全局配置脚本。
1616
- `/etc/profile.d`目录里面所有`.sh`文件
17-
- `~/.bash_profile`:用户的个人配置脚本。
18-
- `~/.bash_login`:如果`~/.bash_profile`没找到,则尝试读取这个脚本(C shell 的初始化脚本)。
17+
- `~/.bash_profile`:用户的个人配置脚本。如果该脚本存在,则执行完就不再往下执行。
18+
- `~/.bash_login`:如果`~/.bash_profile`没找到,则尝试执行这个脚本(C shell 的初始化脚本)。如果该脚本存在,则执行完就不再往下执行
1919
- `~/.profile`:如果`~/.bash_profile``~/.bash_login`都没找到,则尝试读取这个脚本(Bourne shell 和 Korn shell 的初始化脚本)。
2020

21-
发行版更新的时候,会更新`/etc`里面的文件,比如`/etc/profile`,因此不要直接修改这个文件。如果想修改所有用户的登陆环境,就在`/etc/profile.d`目录里面新建`.sh`脚本。
21+
Linux 发行版更新的时候,会更新`/etc`里面的文件,比如`/etc/profile`,因此不要直接修改这个文件。如果想修改所有用户的登陆环境,就在`/etc/profile.d`目录里面新建`.sh`脚本。
2222

2323
如果想修改你个人的登录环境,一般是写在`~/.bash_profile`里面。下面是一个典型的`.bash_profile`文件。
2424

@@ -43,7 +43,7 @@ export EDITOR
4343

4444
可以看到,这个脚本定义了一些最基本的环境变量,然后执行了`~/.bashrc`
4545

46-
`bash`命令的`--login`参数,会强制执行登陆 Session 会执行的脚本。
46+
`bash`命令的`--login`参数,会强制执行登录 Session 会执行的脚本。
4747

4848
```bash
4949
$ bash --login
@@ -61,8 +61,8 @@ $ bash --noprofile
6161

6262
非登录 Session 的初始化脚本依次如下。
6363

64-
- `/etc/bash.bashrc`
65-
- `~/.bashrc`
64+
- `/etc/bash.bashrc`:对全体用户有效。
65+
- `~/.bashrc`:仅对当前用户有效。
6666

6767
对用户来说,`~/.bashrc`通常是最重要的脚本。非登录 Session 默认会执行它,而登陆 Session 一般也会通过调用执行它。由于每次执行 Bash 脚本,都会新建一个非登录 Session,所以`~/.bashrc`也是每次执行脚本都会执行的。
6868

@@ -72,7 +72,7 @@ $ bash --noprofile
7272
$ bash --norc
7373
```
7474

75-
`bash`命令的`--rcfile`参数,指定一个另一个脚本代替`.bashrc`
75+
`bash`命令的`--rcfile`参数,指定另一个脚本代替`.bashrc`
7676

7777
```bash
7878
$ bash --rcfile testrc
@@ -140,12 +140,6 @@ $ bash test.sh
140140

141141
上面例子中,当前 Shell 的变量`foo`并没有`export`,所以直接执行无法读取,但是`source`执行可以读取。
142142

143-
`source`有一个简写形式,可以使用一个点(`.`)来表示。
144-
145-
```bash
146-
$ . .bashrc
147-
```
148-
149143
`source`命令的另一个用途,是在脚本内部加载外部库。
150144

151145
```bash
@@ -158,3 +152,9 @@ function_from_lib
158152

159153
上面脚本在内部使用`source`命令加载了一个外部库,然后就可以在脚本里面,使用这个外部库定义的函数。
160154

155+
`source`有一个简写形式,可以使用一个点(`.`)来表示。
156+
157+
```bash
158+
$ . .bashrc
159+
```
160+

docs/trap.md

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

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
"type": "git",
1818
"url": "git+https://github.com/wangdoc/bash-tutorial.git"
1919
},
20-
"keywords": ["tutorial", "Bash"],
20+
"keywords": [
21+
"tutorial",
22+
"Bash"
23+
],
2124
"author": "",
2225
"license": "CC-BY-SA-4.0",
2326
"bugs": {
@@ -31,7 +34,7 @@
3134
"homepage": "https://github.com/wangdoc/bash-tutorial#readme",
3235
"dependencies": {
3336
"gh-pages": "^2.2.0",
34-
"husky": "^4.2.3",
37+
"husky": "^4.2.5",
3538
"loppo": "latest",
3639
"loppo-theme-wangdoc": "latest"
3740
}

0 commit comments

Comments
 (0)