-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy path12、Shell Script
298 lines (183 loc) · 5.93 KB
/
12、Shell Script
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
Shell Script如果读取到 <CR> 就尝试执行该命令
.sh 文件可以通过 赋予 rx 权限直接执行
或者通过 sh shell.sh 或 bash shell.sh 来执行
sh的文件结构
【1】sh文件的第一行
#!/bin/bash 指定了文件该用哪个 shell 执行,同时也指定了该用什么环境变量来执行(也就是 ~/.bashrc)
【2】sh 开头最好写注释
注释内容包括
1、版本与功能
2、版本信息
3、作者和联系方式
4、建立时间
5、历史记录
【3】定义环境变量
比如 PATH 和 LANG
【4】程序主要部分
【5】程序结束返回码
exit 0
使用 sh shellscript.sh 或直接执行 ./shellscript.sh 时,会创建一个新的 shell 进程来执行这些操作
而使用 source shellscript.sh 或 . shellscript.sh 来执行命令时,shellscript.sh 的内容会直接在当前进程中执行
条件测试命令
test <options>
注意,test 命令只返回 执行结果的返回码,若为真则返回 0,若为假则返回 1。
所以 test 命令不会在屏幕上显示结果
需要使用如下形式的方式来显示结果
test -e /home && echo "yes" || echo "no"
(1) 文件类型判断,形如 test -e <filename>
-e 文件名是否存在 (exist)
-f 文件名是否存在,且为 普通文件 (file)
-d 文件名是否存在,且为 目录 (directory)
-b 文件名是否存在,且为 块设备 (block)
-c 文件名是否存在,且为 字符流设备 (character)
-S 文件名是否存在,且为 套字节文件 (socket)
-p 文件名是否存在,且为 管线文件 (FIFO,pipe)
-L 文件名是否存在,且为 符号链接 (symbolic link)
(2) 文件权限判断,形如 test -r <filename>
-r 文件名是否存在,且当前用户具有 可读 权限
-w 文件名是否存在,且当前用户具有 可写 权限
-x 文件名是否存在,且当前用户具有 可执行 权限
-u 文件名是否存在,且具有 SUID 属性
-g 文件名是否存在,且具有 SGID 属性
-k 文件名是否存在,且具有 Sticky Bit 属性
-s 文件名是否存在,且文件大小不为 0
(3) 文件间的比较,形如 test <file1> -nt <file2>
-nt <file1> 是否比 <file2> 新
-ot <file1> 是否比 <file2> 旧
-ef <file1> 和 <file2> 最终是否指向同一个文件(符号链接也可以)
(4) 整数之间的对比,形如 test <num1> -eq <num2>
-eq <num1> 等于 <num2>
-ne <num1> 不等于 <num2>
-gt <num1> 大于 <num2>
-lt <num1> 小于 <num2>
-ge <num1> 大于等于 <num2>
-le <num1> 小于等于 <num2>
(5) 字符串的判定
-z <str1> 字符串为空
-n <str1> 字符串非空
<str1> == <str2> 两字符串相同(注意空格)
<str1> != <str2> 两字符串不同(注意空格)
(6) 复合判断条件
<exp1> -a <exp2> 当两个表达式都成立时返回 true
<exp1> -o <exp2> 当两个表达式中有一个成立即返回 true
! <exp1> 表达式结果取反
判断符 [ ]
[ ] 在本质上和 test 等价
EG0.Warning
[ -z "${HOME}" ]
注意 [ 之后的空格 以及 ] 之间的空格,若没有空格,则不作为判断符来使用
以及 用双引号 "" 引起来的变量名
EG1.Warning
var1="eZio Pan"
[ -n ${var1} ]
会返回错误
因为第二行会被翻译为 [ -n eZio Pan ]
此时判断符会认为传入了三个参数而报错
正确写法为
[ -n "${var1}" ]
此时该句会被翻译为 [ -n "eZio Pan" ]
就不会报错了
读取传入参数 $<num>
$0 代表要执行的脚本名,注意,无论用 sh shellscript.sh 还是 ./shellscript.sh $0 都是 shellscript.sh
$1 代表第一个传入参数
$2 代表第二个传入参数
...
$# 代表传入脚本的参数总数
$* 代表传入脚本的所有参数,输出格式为 "$1$IFS$2$IFS$3$IFS...", IFS 是 bash 的环境变量,定义了间隔符
$@ 代表传入脚本的所有参数,输出格式为 "$1" "$2" "$3" ...
偏移/舍去 传入参数
shift [偏移数量]
若不指定偏移数量,默认偏移一位
eg.
shift 3
表示去除 $1 $2 $3,将 $4 作为新的 $1 输出,后方的参数依次前推
if 条件判断语句
if [ <condition1> ]
then
<command1>
elif [ <condition2> ]
then
<command2>
...
else
<lastCommand>
fi
case 条件判断语句
case ${<variableName>} in
<case1>)
<command1>
;;
<case2>)
<command2>
;;
...
*)
<lastCommand>
esac
function 函数声明和调用
函数的声明
function <function_name>() {
<command1>
}
注意: 在声明函数的时候,不需要设定任何 伪参数,Bash 的函数只接受以位置定义的传入参数
函数的调用
<function_name> <参数1> <参数2> <参数3> ...
eg.
function PrintOut(){
echo "Your 1st parm is "$1 # $1 代表传入函数的第一个参数
echo "Your 2nd parm is "$2 # $2 代表传入函数的第二个参数
}
PrintOut lalala kokoko
# 返回
Your 1st parm is lalala
Your 2nd parm is kokoko
while..do 循环语句
!条件成立时执行循环内语句
!先执行一次循环才会执行判断
while [ condition ]
do
<command>
done
eg.
n=0
while [ ${n} -le 10 ]; do
echo ${n}
n=$((${n}+1))
done
until..do 循环语句
!条件不成立时结束循环内语句
!先执行一次循环才会执行判断
until [ condition ];
do
<command>
done
eg.上述 while 循环可以改写为
n=0
until [ ${n} -gt 10 ]; do
echo ${n}
((n++)) # 注意,不要写成 $((n++)),这会返回计算结果,导致报错
done
for..do 循环语句
!已知循环次数的循环语句
for <iter> in <content1> <content2> ...
do
<command>
done
eg.上述 until 循环等效于
for n in $(seq 0 10); do
echo $n
done
!for..do 的第二种写法
for ((<起始状态>;<计数器判定条件>;<步幅>))
do
<command>
done
eg.上述 for 循环可以改写为
for ((n=0;n<=10;n++)); do # n<=10 可以改写为 ${n}<=10
echo -n ${n}
done
shell script 的 debug
sh [-nvx] <script.sh>
-n 不执行脚本,只检查语法错误
-v 在执行脚本前打印脚本文件
-x 返回当前执行的每一行脚本与脚本的输出,脚本以 + 开头