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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
linux  bash  shell的使用博大精深,,本人梳理基础知识,整理一下简单的用法,细节请根据需求自行研究。
 
 
1. 计算
# echo $((1+2))
3
# echo $((1+2+3))
6
# echo 3+2+5 |bc
10
 
 
 
2.  if 的用法
if  [ $i - eq  0 ];  then
     xxx
else
     xxx
fi
 
注意下面这2种判断方式:
1) test , && 和 || 的用法 
[root@tvm01 ~] # a=3
[root@tvm01 ~] # test $a -eq 3 && echo 'a' || echo 'b'
a
[root@tvm01 ~] # test $a -eq 4 && echo 'a' || echo 'b' 
b
[root@tvm01 ~] # test $a -eq 4 && echo 'a' || echo 'b' && echo 'c'
b
c
[root@tvm01 ~] # test $a -eq 3 && echo 'a' || echo 'b' && echo 'c' 
a
c
2)不加 if ,也不用  test
[ -d  '/tmp/aaa'  ] ||  mkdir  -p  /tmp/aaa
 
3)整数比较:
- eq  等于,如: if  "$a"  - eq  "$b"  ]   
- ne  不等于,如: if  "$a"  - ne  "$b"  ]   
-gt 大于,如: if  "$a"  -gt  "$b"  ]   
- ge  大于等于,如: if  "$a"  - ge  "$b"  ]   
-lt 小于,如: if  "$a"  -lt  "$b"  ]   
- le  小于等于,如: if  "$a"  - le  "$b"  ]   
<   小于(需要双括号),如:(( "$a"  "$b" ))   
<=  小于等于(需要双括号),如:(( "$a"  <=  "$b" ))   
>   大于(需要双括号),如:(( "$a"  "$b" ))   
>=  大于等于(需要双括号),如:(( "$a"  >=  "$b" )) 
 
4)字符串比较:
通常是这样做的:
if  [ X "$test"  = X "test"  ]
 
= 等于,如: if  "$a"  "$b"  ]   
 
-d 目录
-e 存在
-f 文件
-n 非空字符串
-z 空字符串
 
 
5)来点儿复杂的:
have_program() {
     hash  "$1"  > /dev/null  2>&1
}
# 下面if语句中调用的have_program若为真,则判断为假,反之则进入if语句执行错误提示
dep_check() {
     if  ! have_program  "$1" then
         exit_message  "'${1}' command not found. Please install or add it to your PATH and try again."
     fi
}
# 判断用户的权限
if  [ ` id  -u` - ne  0 ];  then
     echo  "You must run this script as root."
     if  [ -x  /usr/bin/sudo  ];  then
         echo  "Try running 'sudo ${0}'."
     fi
     exit  1
fi  >&2
# 判断几个命令是否可用
echo  "Checking for required packages..."
for  pkg  in  rpm yum python curl;  do
     dep_check  "$pkg"
done
 
  
 
3.  for 的用法
array1=( "d.com"  "e.com"  "f.com" )
len=${ #array1[@]}
 
for  ((i=0;i<$len;i++))
do
     echo  ${array1[$i]}
done
 
for  in  $( seq  1 100); do
     echo  $a
     sleep  1s
done
 
 
4.  case 的用法
case  $1  in
     start|stop|reload)
         $1
         ;;
     *)
         echo  "Usage: $0 [start|stop|reload]"
         ;;
esac
 
 
5.  while 的用法
while  true
do
     echo  "abc"
     read  -p  "请输入: "  abc
     ddd= "$abc"
     if  [ ${ #ddd} -ne 5 ]; then
         echo  "请重新输入!!!"
     else
         break
     fi
done
 
case 结合的用法:
while  getopts  "h"  option;  do
     case  "$option"  in
         h) usage ;;
         *) usage ;;
     esac
done
 
read 结合的用法:
从文件中逐行读入内容,拼接字符串
s= '\n\n'
while  read  line
do
     s= "${s}${line}\n"
done  < /tmp/a .txt
echo  -e $s
 
 
read  ignore结合的用法:
# echo 'a b c d e' |while read ignore args; do echo $args; done        
b c d e
# echo 'a b c d e' |while read ignore ignore args; do echo $args; done
c d e
# cat /etc/init.d/network |grep static-routes --color -A 3                    
         # Add non interface-specific static-routes.
         if  [ -f  /etc/sysconfig/static-routes  ];  then
            grep  "^any"  /etc/sysconfig/static-routes  while  read  ignore args ;  do
               /sbin/route  add -$args
            done
         fi 
其实,这里的ignore也是一个变量:
# echo 'a b c d e' |while read ignore args; do echo "$ignore $args"; done 
a b c d e
# echo 'a b c d e' |while read ignore ignore args; do echo "$ignore $args"; done 
b c d e
 
read 后可以跟多个变量,依次接收传递过来的值。
 
6. 参数
[root@ test  t] # cat t.sh 
#!/bin/bash
#
#  $0 是这个bash文件的名称;
#  $1 是第1个参数;
#  $? 是上一指令的返回值;
#  $* 是该脚本调用的所有参数;
#  $@ 基本与上面的$*相同。区别是:
#      $* 返回的是一个字符串,字符串中用空格分隔开,而 $@ 则返回多个字符串;
#  $# 是所有位置参数的个数;
#  $$ 是返回上一个指令对应的pid
#
ab=($( ls ))
echo  '${ab[@] -> ' ${ab[@]}
echo  '${#ab[@]} -> ' ${#ab[@]}
 
echo  '$0 -> ' $0
echo  '$1 -> ' $1
echo  '$2 -> ' $2
echo  '$? -> ' $?
echo  '$* -> ' $*
echo  '$@ -> ' $@
echo  '$# -> ' $#
echo  '$$ -> ' $$
[root@ test  t] # sh t.sh zzz yyy xxx www -h
${ab[@] -> set_color.sh t.sh
${ #ab[@]} -> 2
$0 -> t.sh
$1 -> zzz
$2 -> yyy
$? -> 0
$* -> zzz yyy xxx www -h
$@ -> zzz yyy xxx www -h
$ # -> 5
$$ -> 30383
 
 
7. 正则
  正则表达式匹配 "=~"
  [[ $XX =~ ^$XXX ]] 
The =~ Regular Expression matching operator within a double brackets  test  expression.
 
$ [[  "# test2"  =~ ^# ]] &&  echo  yes  ||  echo  no
yes
 
 
8. 截取字符串
 
假设有:
f= "/a/b/c/d/e.name.ext"
 
则:
# basename $f
e.name.ext
# dirname $f    
/a/b/c/d
 
特殊用法:利用${}中的 #,%,*来输出指定的内容
1)去掉第一个/,以及左边的字符串 
# echo ${f#*/}
a /b/c/d/e .name.ext
 
2)去掉最后1个/,以及左边的字符串
# echo ${f##*/}
e.name.ext
 
3)去掉最后一个/,以及右边的字符串
# echo ${f%/*} 
/a/b/c/d
 
4)去掉第一个/,以及右边的字符串
# echo ${f%%/*} 
(空)
 
上面,是根据“/”来做分割,也可以用“."来分隔,不妨一试。
# echo ${f#*.} 
name.ext
# echo ${f##*.}
ext
# echo ${f%.*} 
/a/b/c/d/e .name
# echo ${f%%.*}
/a/b/c/d/e
 
 
9. 脚本放入后台,输出到日志
sh  test .sh >1.log 2>&1 &
sh  test .sh > /dev/null  2>&1 &
这里需要理解几个小东西的作用:
/dev/null    理解成空设备,这是一个特殊的文件,这里的作用是丢弃输出的内容
2>&1        0 输入  1 输出  2 错误 这里是将2重定向到1
&           将 test .sh放入后台执行,请思考,还有其他的什么方式也可以将程序放入后台?
 
 
10. 管道
通过“|” 把输出导入到另一个程序的输入中去处理,例如:
echo  'abc, def'  | cut  -d  ','  -f 1
 
 
11. 命令跟踪调试
sh -x  test .sh
 
 
12. 快捷键
Ctrl + a 切换到命令行开始
Ctrl + b - Move back a char
Ctrl + c 终止命令
Ctrl + d 退出shell, logout
Ctrl + e 切换到命令行末尾
Ctrl + l 清除屏幕内容
Ctrl + k 剪切清除光标之后的内容
ctrl + q 恢复刷屏
Ctrl + r 在历史命令中查找
ctrl + s 可用来停留在当前
Ctrl + u 清除剪切光标之前的内容
Ctrl + y 粘贴刚才所删除的字符
Ctrl + z 转入后台运行
!! 重复执行最后一条命令
↑(Ctrl+p) 显示上一条命令
↓(Ctrl+n) 显示下一条命令
!$ 显示系统最近的一条参数
 
 
13. 在shell中调用python的方法
# python <<'_EOF'        
import  sys
 
print(sys.version)  
_EOF
 
2.6.6 (r266:84292, Jan 22 2014, 09:42:36) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)]
 
shell传递中文到python出现异常时:
export  LANG= "en_US.UTF-8" ;
/usr/local/bin/python3   xxx.py
 
 
14. 创建临时目录的方法
tempdir=`mktemp -d`
cd  "$tempdir"
 
15. 一个简单的密码生成方法
pw=` date  +%N| cut  -c1-8`
man  date 查看:
%N     nanoseconds (000000000..999999999)
man  cut 查看:
?-c, --characters=LIST
               select  only these characters
  
16. 简单 ping 一下C段的IP
subnet=192.168.1;  for  in  {1..254}; 
do 
     ping  -c 1 -w 1 ${subnet}.${i} > /dev/null  &&  echo  "${subnet}.${i}: up"  ||  echo  "${subnet}.${i}: down"
done
 
17. 字符串反转
# echo 'abcde' |rev
edcba
 
18.  crontab 的用法
1)格式不清楚可以这样:
cat  /etc/crontab  或者  man  crontab
 
2)注意:用户权限,是否需要特殊的环境变量。
3)注意:特殊符合,例如:% 在  crontab  中是特殊的意义(换行)
Percent-signs (%)  in  the  command , unless escaped with backslash (\), will be changed into new-line characters, and all data after the first % will be sent to the  command  as standard input.
举例:
【错误】
0 2 * * *  echo  'test'  > /tmp/test_ $( date  +%Y%m%d).log 2>&1 &
【正确】
0 2 * * *  echo  'test'  > /tmp/test_ $( date  +\%Y\%m\%d).log 2>&1 &
 
 
19. 在 shell 中使用 Here Document 的使用注意
常见写法,可以使用变量:
test =$(blkid  /dev/vg0/lv01  | cut  -d '"'  -f2)
cat  <<_EOF >> /etc/fstab
UUID=$ test  /data                    xfs     defaults        0 0
_EOF
 
换一种,则无法使用变量:
cat  << '_EOF'  >> /etc/fstab
UUID=$ test  /data                    xfs     defaults        0 0
_EOF
 
 
20. 测试主机内存占用状况(模拟分配最少 1 GiB 内存)
python -c  "import time;d='a'*1024*10**6;time.sleep(3600)"  &
 
 
21. 排序的疑问
[root@tvm01 ~] # cat a.test 
a
b
c
d
e
a
b
c
d
e
1
2
3
4
5
1
1
2
2
3
3
[root@tvm01 ~] # cat a.test |uniq |sort      
1
1
2
2
3
3
4
5
a
a
b
b
c
c
d
d
e
e
[root@tvm01 ~] # cat a.test |sort |uniq |sort      
1
2
3
4
5
a
b
c
d
e
上述2者的效果不一样,为何?
原因: uniq 命令隔行重复是无效的,针对这种情况,需要先用 sort 排序再 uniq
 
 
22、临时启用一个端口来测试
python -m SimpleHTTPServer 8081
这个简单的http服务器,还可以当作 ftp
 
 
23、示例随机字符的生成:得到一个MAC地址的3种方式
echo  "AA:BB:`dd if=/dev/urandom count=1 2>/dev/null |md5sum |sed -e 's/^\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4/'`"
echo  "AA:BB:`for i in {1..4};do printf " %0.2X: " $[ $RANDOM % 0x100 ]; done |sed 's/:$/\n/'`"
echo  "AA:BB:`od /dev/urandom -w4 -tx1 -An |sed -e 's/ //' -e 's/ /:/g' |head -n 1`"
 
 
 
24、在shell中使用递归的一个小示例
需求:下载一个小说的文字内容。
~] # cat test.sh 
#!/bin/bash
#
 
do_rewrite() {
     ff=$1
     echo  "[*] Convert -> ${ff}"
     wget -q http: //www .zanghaihuawang.com /laojiumen/ ${ff}.html -O old/${ff}.html
     grep  'h2'  old/${ff}.html > /dev/null
     if  [ $? - eq  1 ];  then
         echo  '[E] empty file.'
         exit  1
     else
         cat  << '_EOF'  >new/${ff}.html
<html xmlns= "http://www.w3.org/1999/xhtml" >
< head >
     <meta http-equiv= "content-type"  content= "text/html; charset=utf-8"  />
< /head >
<body>
_EOF
         sed  -n  '/<h2>/,/\[Enter\]/p'  old/${ff}.html | sed  's/\/laojiumen\///'  >>new/${ff}.html
         cat  << '_EOF'  >>new/${ff}.html
< /body >
< /html >
_EOF
         f_next=$( cat  new/${ff}.html | grep  'pager_next'  | grep  -Eo  '[0-9]+' )
         if  [ -z ${f_next} ];  then
             echo  '[E] next file not found.'
             exit  2
         else
             do_rewrite ${f_next}
         fi
     fi
}
 
do_gb2312_to_utf8() {
     #yum -y groupinstall "Development Tools" && wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz && tar zxvf libiconv-1.14.tar.gz && cd libiconv-1.14 && ./configure && make && make install
     for  in  ` ls  new/`;  do  iconv -c -f gb2312 -t utf-8  test /$i >new_utf8/$i; done
}
 
mkdir  -p old new
do_rewrite $1
 
 
25、 set 的用途
1)设置参数
在脚本中:
# cat t.sh 
set  z1 y1 x1 w1
echo  '$1 -> ' $1
echo  '$2 -> ' $2
echo  '$@ -> ' $@
echo  '$# -> ' $#
 
# sh t.sh z y x w
$1 -> z1
$2 -> y1
$@ -> z1 y1 x1 w1
$ # -> 4
 
在命令行:
[root@ttt ~] # set z y x w
[root@ttt ~] # echo $#    
4
[root@ttt ~] # echo $@
z y x w
 
 
2)设置选项
set  -e :命令执行结果不为0,则退出
set  -x :调试输出
 
其他请参考 man 手册
 
 
26、如何审计操作
提供一些思路:
script
PROMPT_COMMAND
用法,请搜索相关主题。
 
 
 
27、查看内存占用:
ps  -u appuser  -wo rss=, comm = -- sort  -rss |  while  read  -r rss  comm  do  echo  $((rss /1024 )) "MB -"  $ comm done  | head  -n 10
 
 
28、如何使用!$
[root@ test  ~] # ls /tmp/
cvm_init.log  net_affinity.log  sagent.pid  setRps.log
[root@ test  ~] # echo !$
echo  /tmp/
/tmp/
 
显然,要调用上一条指令的最后一个参数,不妨试试 !$
 
 
28、查看 ip=192.168.200.201 监听的端口(8300-8599这个范围的):
ss -ant | awk  '$4~/192.168.200.201:8[3-5]/ {print $0}'
 
 
29、防火墙常用操作
放行端口
iptables -A INPUT -s 1.2.3.4 /32  -p tcp -m tcp --dport 8080 -j ACCEPT
iptables -A INPUT -s 1.2.3.4 /32  -p tcp -m tcp --dport 4000:4099 -j DROP
 
端口转发
iptables -t nat -A PREROUTING -d 服务器外网IP /32  -p tcp -m tcp --dport 8080 -j DNAT --to-destination 服务器内网IP
iptables -t nat -A POSTROUTING -d 服务器内网IP /32  -p tcp -m tcp --dport 8080 -o eth0 -j MASQUERADE
 
 
30、查看和清理指定用户下的进程
ps  -U username
ps  -U username -L
ps  -U username | awk  '{print $1}'  | grep  -Eo  '[0-9]+'  | xargs  -i  kill  {}
 
 
31、$ 'string'  的用法
参考:
http: //www .gnu.org /software/bash/manual/html_node/ANSI_002dC-Quoting .html
https: //stackoverflow .com /questions/18626209/bash-syntax-error-near-unexpected-token
 
是不是在 init.d 的脚本中常看到这样一段:
echo  $ "Usage: xxx"
 
这个 dollar sign $ 是啥意思呢?
 
Words of the form $ 'string'  are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.
 
就是说,字符串前边有个美元符号,意味着可以使用转义符。
 
 
 
32、base64编码解码
echo  -n  "foo"  |base64
base64 -d <<<  "Zm9v"
while  read  line;  do  cnt=$( echo  $line | wc  -c); [ $cnt -gt 1000 ] &&  continue echo  $line; echo  -e  '\n----->\n' ; echo  -n $line |base64 -d;  echo  -e  '\n\n' done <1.txt
 
 
33、对比 here document 还有一种 here string 的写法
<< denotes a here document
<<< denotes a here string
 
cat  <<<  'hi there'
hi there
 
read  first second <<<  "hello world"
echo  $second $first
 
 
 
34、进制转换
16 进制 -> 10 进制
[root@dev8 run] # echo $((0x13b))
315
 
10 进制 -> 16 进制
[root@dev8 run] # echo "0x$(echo "obase=16;315"|bc |tr 'A-Z' 'a-z')"
0x13b