301# 注释
2:<<EOF,冒号在shell中也是命令,表示什么都不做。
3echo "I am oldboy"
4echo "I am oldboy"
5echo "I am oldboy"
6EOF #必须顶格写
7
8# 井号作为注释
9在目前的Linux中用bash和sh都是一样的,因为sh是bash的软连接。
10
11shell脚本的执行
121. bash script-name
132. path/to/script-name或./script-name
143. source script-name或. script-name
154. sh<script-name或cat script-name|sh
16
17bash script_name # 新开启一个子shell
18.或者source # 不会新开一个子shell
19
20bash脚本的一些规范化建议:
211.开头加脚本解释器
222.附带作者及版权信息
233.脚本扩展名为*.sh
244.脚本存放在固定的目录下
255.脚本中不用中文
266.成对的符号一次书写完成
277.循环格式一次性输入完成
28
29登录shell:优先/etc/profile,然后加载~/.bash_profile ,再次加载~/.bashrc,最后加载/etc/bashrc
30非登录shell:/etc/bashrc,~/.bashrc在执行一个非登录shell时调用
登录shell:优先/etc/profile,然后加载~/.bash_profile ,再次加载~/.bashrc,最后加载/etc/bashrc
非登录shell:/etc/bashrc,~/.bashrc在执行一个非登录shell时调用
变量
xxxxxxxxxx
301定义环境变量
2export TEST=1
3TEST=1
4export TEST
5declare -x TEST=1
6
7shell变量的使用和命名规范建议:
8针对变量名:(一般驼峰法则或者是下划线分隔都行)
91)变量名的定义要有一定的命令规范,并且要见名知意
102)变量名仅能使用字母,数字,下划线中的任意多个字符,并且以字母开头
11针对变量内容:
123)在脚本汇总定义普通字符串变量,精良把变量的内容用双引号括起来
134)单独数字的变量内容可以不加引号
145)希望变量的内容原样输出要加单引号
156)希望变量的值应用命令并获取命令的结果就用反引号或${}
16针对赋值符号:
177)变量定义使用赋值符号=,赋值符号的两端不要有空格
18针对变量输出:
198)使用或者输出变量的内容,可用$变量名,例如echo $PATH
209)拖用变量名db和面有其它字符连接的时候,就必须给变量名加上大括号{},如$db_t改为${db}_t
21
22
23普通变量(局部变量)
24当前用户或者脚本中生效,离开当前用户或者脚本就会失效。
25变量的名称:遵循驼峰法则或者下划线分隔单词
26变量内容:
27变量名=value #<==不加引号。 ##解析变量或者命令,然后输出,纯数字选择不加引号。
28变量名='value' #<==加单引号。 ###所见即所得
29变量名="value" #<==加双引号。 ##解析变量或者命令,然后输出,字符串默认选择双引号,可以把要定义的内容作为一个整体。
30变量名=`ls` 或变量名=$(ls)
xxxxxxxxxx
561# 变量引用和变量替换
2`command_name_str` 反引号强引用,和$()等同var_name=`ls`
3
4$(command_name_str) $(),命令置换 var_name=$(ls)
5
6${var_name} 变量引用 ${var_name}_d
7
8$var_name 变量引用 $var_name_d ≠ ${var_name}_d
9
10
11位置变量 描述
12$0 脚本的路径或名称
13$n n的范围是0~9,表示传入的第n个参数的值
14$# 脚本中传入参数的个数
15$* 传入的所有参数,但合并为一个参数
16$@ 传入的所有参数,不合并为一个参数
17状态变量 描述
18$? 上一次执行程序的返回结果
19$$ 当前执行脚本的进程号
20$! 获取上一个后台工作进程的进程号
21$_ 获取上一个执行脚本的最后一个参数
22
23
24变量子串 描述
25${parameter} 返回变量的内容
26${#parameter} 返回变量的长度,也适合特殊变量。
27 echo ${#TEST}
28 expr length "${TEST}"
29 echo $TEST|awk '{print length ($0)}'
30${parameter:offset} 从offset开始取字串到结尾
31${parameter:offset:length} 从offset开始取length长度的字串
32${parameter#word} 从变量开头开始删除最短匹配的word字串,可用通配符
33${parameter##word} 从变量开头开始删除最长匹配的word字串,可用通配符
34${parameter%word} 从变量结尾开始删除最短匹配的word字串,可用通配符
35${parameter%%word} 从变量结尾开始删除最长匹配的word字串,可用通配符
36${parameter/pattern/string} 使用string代替第一个匹配的pattern,可用通配符
37${parameter//pattern/string} 使用string代替所有匹配的pattern,可用通配符
38
39# shell特殊变量扩展(冒号可以省略)
40${parameter:-word} result=${var:-word}
41 如果变量var值为空或未赋值,那么就把值word赋值给result,但是不复制给var变量
42 find $path -name "*.log" -mtime +7 | xargs rm -rf
43 find ${path:-/tmp} -name "*.log" -mtime +7 | xargs rm -rf
44 典型应用:httpd的启动脚本
45
46${parameter:=word} result=${var:-word}
47 如果变量var值为空或未赋值,那么就把值word赋值给result,然后再赋值给变量var
48
49
50${parameter:?word} result=${var:-word}
51 如果变量var值为空或未赋值,那么就把值word当做bash错误提示输出
52 -bash: var:word
53
54${parameter:+word} result=${var:-word}
55 如果变量var值为空或未赋值,那么无操作,如果变量var不为空,就把值赋值给result,但是不赋值给var变量
56
运算符号
xxxxxxxxxx
141常见的运算符 描述
2+、- # 加法、减法
3*、/、% # 乘法、除法、取余(模)
4** # 幂运算
5++、-- # 增加或减少,前置和后置表达式的结果是不一样的
6!、&&、|| # 逻辑非、逻辑与、逻辑或
7<、<=、>、>= # 小于、小于等于、大于、大于等于
8==、!=、= # 相等、不相等、对于字串可表示相当
9<<、>> # 左移位、右移位
10~、&、|、^ # 按位取反、按位与、按位或、安慰异或
11=、+=、-=、*=、/=、%= # 赋值、增强赋值
12 # 在强类型语言(Java)中,a+=b和a=a+b是有区别的,
13 # 他们的区别是:在处理过程中各自数据类型有转换,a+=b<=>a=(a+b),它是做了数据类型强制转换的
14
运算方法
xxxxxxxxxx
371shell中常用的数学运算方法 描述
2(()) 整数计算,效率高
3let 整数运算,类似(())
4expr 可用于整数运算,但是还有很多其它的功能
5bc 适合整数和小数运算
6$[] 整数计算
7awk 适合整数和小数运算
8 echo 2.1 1.4|awk '{print $1*$2}'
9declare 定义变量值和属性,-i参数用于定义整型变量,做运算
10 declare -i a=4+5
11
12表达式 描述
13$(i=i+1) 运算后赋值,即将i+1的运算结果复制给变量i。注意不能用echo ((i=i+1))来输出表达式的值,但是可以用echo $((i=i+1))来输出。
14i=$((i+)) 可以在(())前加$符号,将表达式运算后复制给i
15((8>7&&5==5)) 可以进行比较运算,还可以加入逻辑与和逻辑或,用于条件判断
16echo $((2+1)) 需要直接输出运算表达式结果时可以在(())前面加上$符号
17
18
19expr判断一个变量是否为整数
20
21expr 2 + $1 &>/dev/null
22if [ $? -eq 0 ];then
23 echo "$1 is integer"
24else
25 echo "$1 is not integer"
26fi
27
28判断扩展名
29
30expr "$1" : ".*\.txt" &>/dev/null
31if [ $? -eq 0 ];then
32 echo "file extension is txt"
33else
34 echo "file extension not is txt"
35fi
36计算字符长度
37expr length "str"
用户交互
xxxxxxxxxx
531
2a=$1
3b=$2
4echo "a-b=$(($a-$b))"
5echo "a+b=$(($a+$b))"
6echo "a*b=$(($a*$b))"
7echo "a/b=$(($a/$b))"
8echo "a**b=$(($a**$b))"
9echo "a%b=$(($a%$b))"
10
11-p 提示
12-t 等待用户输入的时间
13read -t 30 -p "请输入一个数字:"
14
15read -p "请输入两个数字:" a b
16echo "a-b=$(($a-$b))"
17echo "a+b=$(($a+$b))"
18echo "a*b=$(($a*$b))"
19echo "a/b=$(($a/$b))"
20echo "a**b=$(($a**$b))"
21echo "a%b=$(($a%$b))"
22
23
24cat <<EOF
25 1.install lamp
26 2.install lnmp
27 3.exit
28EOF
29read -p "请选择一个序号(必须是数字):" num
30#1.判断是否为整数
31expr 2 + $num &>/dev/null
32if [ $? -ne 0 ]
33then
34 echo "Usage:$0 {1|2|3}"
35 exit 1
36fi
37
38#2.判断执行处理
39if [ $num -eq 1 ]
40then
41 echo "install lamp..."
42elif [ $num -eq 2 ]
43then
44 echo "install lnmp..."
45elif [ $num -eq 3 ]
46then
47 echo "bye."
48 exit
49else
50 echo "Usage:$0 {1|2|3}"
51 exit 1
52fi
53
条件测试
xxxxxxxxxx
1331条件表达式6种写法:if,while
2 语法1: test <测试表达式>
3 语法2: [ <测试表达式> ] #两端有空格
4 语法3:[[ <测试表达式> ]] #两端有空格
5 语法4:((<测试表达式>)) #不需要空格
6
7 语法5:(命令表达式)
8 语法6:`命令表达式`
9
10编程语法:
11[ <测试表达式> ] && 命令1
12如果前面表达式成功,那么就执行后面命令。
13
14[ <测试表达式> ] || 命令1
15如果前面表达式失败,那么就执行后面命令。
16
17[ <测试表达式> ] && {
18命令1
19命令2
20命令3
21}
22如果前面表达式成功,那么就执行后面命令。
23
24[ <测试表达式> ] && 命令1 || 命令2
25如果前面表达式成功,那么就执行命令1,否则执行命令2。
26
27[ <测试表达式> ] && {
28命令1
29命令2
30}||{
31命令3
32命令4
33}
34如果前面表达式成功,那么就执行命令1,2,否则执行命令3,4。
35
36
37常用文件测试表达式 描述
38-d 文件,directory
39-f 文件,file
40-e 文件,exist
41-r 文件,read
42-s 文件,size
43-w 文件,write
44-x 文件,executable
45-L 文件,link
46f1 -nt f2,newer than
47其它内容可以直接man test 查找。
48
49
50在[]以及test中使用 在(())和[[]]中使用 描述
51-eq ==或= equal,等于
52-ne != not equal,不等于
53-gt > greater than,大于
54-ge >= greater equal,大于等于
55-lt < less than,小于
56-le <= less equal,小于等于
57
58注:[ ]是比较老旧的写法,[[ ]]是比较新的用法,它支持[ ]中的写法
59
60字符串测试表达式
61[ -n "字符串" ] 字符串长度[不]为0,表达式为真。 not zero。
62[ -z "字符串" ] 字符串长度为0,表达式为真。 zero。
63[ "字符串1" == "字符串2" ] 两个字符串相同则为真。
64[ "字符串1" !== "字符串2" ] 两个字符串不相同则为真。
65
66
67read -p "pls input two num:" a b
68
69if [ -z "$b" ]
70then
71 echo "请输入两个数"
72 exit 1
73fi
74expr $a + $b + 1 &>/dev/null
75if [ $? -ne 0 ]
76then
77 echo "Usage:$0 num1 num2"
78 exit 1
79fi
80
81
82
83read -p "please input two integer number." a b
84
85[ -z "$b" ] &&{
86 echo "please input two integer number."
87 exit 1
88}
89
90expr $a + $b + 1 &>/dev/null
91[ $? -ne 0 ] &&{
92 echo "please input two integer number."
93 exit 2
94}
95
96if [ $a -gt $b ];then
97 echo "$a>$b"
98 exit 0
99elif [ $a -eq $b ];then
100 echo "$a=$b"
101 exit 0
102else
103 echo "$a<$b"
104 exit 0
105fi
106
107
108在[ ]和test中 在[[]]和(())中 描述
109-a && and,与
110-o || or,或
111! ! not,非
112注:[ ]是比较老旧的写法,[[ ]]是比较新的用法,它支持[ ]中的写法
113[] [[]] (()) 这些符号之间连接 使用&& ||
114
115
116+-----------------+----------------+------------------+-----------------+-------------------+
117| 条件表达式符号 [] test [[]] (())
118+-----------------+----------------+------------------+-----------------+-------------------+
119| 边界是否需要空格 需要 需要 需要 不需要
120+-----------------+----------------+------------------+-----------------+-------------------+
121| 逻辑操作符 !、-a、-o !、-a、-o !、&&、|| !、&&、||
122+-----------------+----------------+------------------+-----------------+-------------------+
123| 整数比较操作符 -eq、-gt -eq、-gt -eq、-gt =、>、<
124| -lt、-ge -lt、-ge -lt、-ge、-le >=、<=
125| -le -le 或
126| =、>、<
127| >=、<=
128+-----------------+----------------+------------------+-----------------+-------------------+
129| 字符串比较操作符 =、==、!= =、==、!= =、==、!= =、==、!=
130+-----------------+----------------+------------------+-----------------+-------------------+
131| 是否支持通配符 不支持 不支持 支持 不支持
132+-----------------+----------------+------------------+-----------------+-------------------+
133
vim配置
xxxxxxxxxx
681set nocompatible
2set history=100
3filetype on
4filetype plugin on
5filetype indent on
6set autoread
7set mouse=c
8syntax enable
9set cursorline
10hi cursorline guibg=#00ff00
11hi CursorColumn guibg=#00ff00
12set foldenable
13set foldmethod=manual
14set foldcolumn=0
15setlocal foldlevel=3
16set foldclose=all
17nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' : 'zo')<CR>
18set expandtab
19set tabstop=4
20set shiftwidth=4
21set softtabstop=4
22set smarttab
23set ai
24set si
25set wrap
26set sw=4
27set wildmenu
28set ruler
29set cmdheight=1
30set lz
31set backspace=eol,start,indent
32set whichwrap+=<,>,h,l
33set magic
34set noerrorbells
35set novisualbell
36set showmatch
37set mat=4
38set hlsearch
39set ignorecase
40set encoding=utf-8
41set fileencodings=utf-8
42set termencoding=utf-8
43set smartindent
44set cin
45set showmatch
46set guioptions-=T
47set guioptions-=m
48set vb t_vb=
49set laststatus=4
50set pastetoggle=<F9>
51set background=dark
52highlight Search ctermbg=black ctermfg=white guifg=white guibg=black
53autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"
54func SetTitle()
55 if expand("%:e") == 'sh'
56 call setline(1, "#!/bin/bash")
57 call setline(2, "##############################################################")
58 call setline(3, "# File Name: ".expand("%"))
59 call setline(4, "# Version: V1.0")
60 call setline(5, "# Author: meizy")
61 call setline(6, "# Organization: ")
62 call setline(7, "# Contact: meizypleased@qq.com")
63 call setline(8, "# Created Time : ".strftime("%F %T"))
64 call setline(9, "# Description:")
65 call setline(10, "##############################################################")
66 endif
67endfunc
68
流程控制语句语法
xxxxxxxxxx
2231if statement
2if <condition>;then
3 statement
4fi
5if <condition>;then
6 statement
7else
8 statement
9fi
10if <condition>;then
11 statement
12elif <condition>;then
13 statement
14elif <condition>;then
15 statement
16...
17else
18 statement
19fi
20
21例1:如果不存在/backup目录就创建。
22考查if单分支
23例2:开发Shell脚本判断系统剩余内存的大小,如果低于100MB就提示内存不足,否则提示内存充足。
24例3:分别使用变量定义、read读入及脚本传参方式实现比较2个整数的大小。
25例4:打印一个菜单如下,当用户选择对应的数字时,就执行对应项的应用。
26 1.install lamp
27 2.install lnmp
28 3.exit
29
30
31cat <<EOF
32 1.install lamp
33 2.install lnmp
34 3.exit
35EOF
36read -p "请选择一个序号(必须是数字):" num
37#1.判断是否为整数
38expr 2 + $num &>/dev/null
39if [ $? -ne 0 ]
40then
41 echo "Usage:$0 {1|2|3}"
42 exit 1
43fi
44
45#2.判断执行处理
46if [ $num -eq 1 ]
47then
48 echo "install lamp..."
49elif [ $num -eq 2 ]
50then
51 echo "install lnmp..."
52elif [ $num -eq 3 ]
53then
54 echo "bye."
55 exit
56else
57 echo "Usage:$0 {1|2|3}"
58 exit 1
59fi
60
61# case语句
62case statement
63case variable in
64 value1)
65 statement
66 ;;
67 value2)
68 statement
69 ;;
70 ...
71 valuen)
72 statement
73 ;;
74 *)
75 statement
76 ;; #这里可以省略,前面都不可以省略
77esac
78
79
80cat <<EOF-
811.apple
822.pear
833.banana
844.cherry
85 EOF
86
87
88
89cat <<EOF
901.apple
912.pear
923.banana
934.cherry
94EOF
95
96
97cat <<'EOF'
98$PATH
99EOF
100
101
102cat <<EOF
103$PATH
104EOF
105
106
107rsyncd启动脚本
108
109
110start(){
111 rsync --daemon
112 retval=$?
113 if [ $retval -eq 0 ]
114 then
115 echo "rsync startup ok"
116 return $retval
117 else
118 echo "rsync startup fail"
119 return $retval
120 fi
121}
122stop(){
123 killall rsync
124 retval=$?
125 if [ $retval -eq 0 ]
126 then
127 echo "rsync stop ok"
128 return $retval
129 else
130 echo "rsync stop fail"
131 return $retval
132 fi
133}
134case "$1" in
135 start)
136 start
137 retval=$?
138 ;;
139 stop)
140 stop
141 retval=$?
142 ;;
143 restart)
144 stop
145 sleep 1
146 start
147 retval=$?
148 ;;
149 *)
150 echo "usage:$0 {start|stop|restart}"
151 exit 1
152esac
153exit $retval
154
155输出内容时可以调用系统函数库
156
157. /etc/init.d/functions
158action "service starting " /bin/ture
159action "service staring" /bin/false
160
161rsyncd启动脚本
162
163. /etc/init.d/functions
164lockfile=/var/lock/subsys/rsyncd
165rsyncd_pid_file_path=/var/run/rsyncd.pid
166
167start(){
168 rsync --daemon
169 retval=$?
170 if [ $retval -eq 0 ]
171 then
172 action "rsync startup" /bin/true
173 touch $lockfile
174 return $retval
175 else
176 action "rsync startup" /bin/false
177 return $retval
178 fi
179}
180stop(){
181 if test -s "$rsyncd_pid_file_path";then
182 rsyncd_pid=`cat $rsyncd_pid_file_path`
183 if (kill -0 $rsyncd_pid &>/dev/null);then # pid对应的进程是否真实存在
184 kill $rsyncd_pid
185 rm -f $lockfile >/dev/null
186 retval=$?
187 if [ $retval -eq 0 ]
188 then
189 action "rsync stop" /bin/true
190 return $retval
191 else
192 action "rsync stop" /bin/false
193 return $retval
194 fi
195 else
196 echo "rsyncd process is no exists."
197 return 2
198 fi
199 else
200 echo "$rsyncd_pid_file_path is not exists,or rsyncd not start."
201 fi
202}
203case "$1" in
204 start)
205 start
206 retval=$?
207 ;;
208 stop)
209 stop
210 retval=$?
211 ;;
212 restart)
213 stop
214 sleep 1
215 start
216 retval=$?
217 ;;
218 *)
219 echo "usage:$0 {start|stop|restart}"
220 exit 1
221esac
222exit $retval
223
xxxxxxxxxx
1101for statement syntax
2for variable in list
3do
4 statement
5done
6for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
7do
8 statement
9done
10
11获取列表
12(1) 直接给出列表;
13(2) 整数列表:
14(a) {start..end}
15(b) $(seq [start [step]] end)
16(3) 返回列表的命令;
17$(COMMAND)
18(4) glob 通配的方式
19(5) 变量引用;
20$@, $*
21
22
23 #!/bin/bash
24 for((j=1;j<=9;j++));do
25 for((i=1;i<=j;i++))do
26 echo -e -n "${i}X${j}=$[$i*$j]\t"
27 done
28 echo
29 done
30
31将文件中的finished去掉
32 准备文件touch stu_{1..10}_finished.jpg
33
34 ls *.jpg|awk -F "_finished" '{print "mv",$0,$1$2}'|bash
35
36 rename "_finished" "" *.jpg #rename to file
37
38 #!/bin/bash
39 for file in `ls ./*.jpg`
40 do
41 mv $file `echo ${file/_finished/}`
42 done
43信号编号 短名称 定义
441 HUP 挂起
452 INT 键盘中断
463 QUIT 键盘退出
479 KILL 中断(无法拦截
4815 TERM 终止
4918 CONT 继续
5019 STOP 停止(无法拦截)
5120 TSTP 键盘停止
52note:先用SIGTERM 再用 SIGKILL 以避免SIGKILL可能造成的误用
53
54
55sh while1.sh &
56
57把脚本while1.sh放到后台执行(后台运行脚本时常用)*
58
59nohup while1.sh &
60
61使用nohup把脚本while1.sh放到后台执行,但消息会输出到标准输出
62
63ctl+c
64
65停止执行当前脚本或任务
66
67ctl+z
68
69暂停执行当前脚本或任务
70
71bg
72
73把当前脚本或任务放到后台执行,bg可以理解为background
74
75fg
76
77把当前脚本或任务拿到前台执行,如果有多个任务,可以使用fg加任务编号调出对应脚本任务,如fg 2,调出第二个脚本任务,fg可以理解为frontground
78
79jobs
80
81查看当前执行的脚本或任务
82
83kill
84
85关闭执行的脚本任务,即以“kill %任务编号”的形式关闭脚本,这个任务编号,可以通过jobs获得
86
87
88常用进程管理命令
89
90后台运行 &、nohup、screen(运维人员)
91
92l kill、killall、pkill:杀掉进程。
93l ps:查看进程。
94l pstree:显示进程状态树。
95l top:显示进程。
96l renice:改变优先权。
97l nohup:用户退出系统之后继续工作。
98l pgrep:查找匹配条件的进程。
99l strace:跟踪一个进程的系统调用情况。
100l ltrace:跟踪进程调用库函数的情况。
101
102
103nohup和&U区别
104
105no hangup的缩写,意即“不挂断”, 忽略所有挂断(SIGHUP)信号,不挂断的运行,注意没有后台运行功能,用nohup运行命令可以使命令永久的执行下去,和用户终端没有关系,例如我们断开SSH连接都不会影响他的运行,注意了nohup没有后台运行的意思;&才是后台运行。&是指在后台运行,但当用户退出(挂起)的时候,命令自动也跟着退出,那么把nohup和&结合起来用nohup COMMAND &这样就能使命令永久的在后台执行
106
107&:放入后台,当session断掉,会受到SIGHUP信号,直接关闭,Ctrl+C无法关闭,输出会放到前台。
108nohup:nohup: ignoring input and appending output to ‘nohup.out’,Ctrl+C程序收到SIGINT信号后,直接关闭,session断掉进程会自动把进程ID为1的进程当做父进程仍然运行,输出不会放到前台,。
109nohup和&:键入Ctrl + C,发送SIGINT信号和关闭session,发送SIGHUP信号都不能关闭。
110
xxxxxxxxxx
751while condition|true|false while read line
2do do
3 statement statement
4done done < /path/to/filename
5
6cat /path/to/filename | while read line exec </path/to/filename
7do while read line
8 statement do
9done statement
10这里会开启一个子shell,所以while外无法使用while中处理的变量。 done
11
12 #
13 read -p "Enter a user name: " username
14
15 while true; do
16 if who | grep "^$username" &> /dev/null; then
17 break
18 fi
19 sleep 3
20 done
21
22 echo "$username logged on." >> /tmp/user.log
23
24 #!/bin/bash
25 read -p "Enter a option: " option
26 while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ]; do
27 read -p "Wrong option, Enter again: " option
28 done
29
30 #!/bin/bash
31 while read line;do
32 if [ $[`echo $line | cut -d: -f3` % 2] -eq 0 ];then
33 echo -e -n "username: `echo $line | cut -d: -f1`\t"
34 echo "uid: `echo $line | cut -d: -f3 `"
35 fi
36 done < /etc/passwd
37
38 #!/bin/sh
39 while true
40 do
41 uptime >>/tmp/uptime.log
42 sleep 2 # usleep微妙
43 done
44
45
46猜数字游戏。首先让系统随机生成一个数字,给这个数字定一个范围(1-60),让用户输入猜的数字,对输入进行判断,如果不符合要求,就给予高或低的提示,猜对后则给出猜对用的次数,请用while语句实现。
47提示:可以赋予一个猜水果的价格游戏。
48分析:
491)给这个数字定一个范围(1-60)
50 echo $((RANDOM%60)) 执行脚本后是固定的,例如;50
51
522)read -p "输入猜数字:" num
53用户输入的数字和已知的随机数比较。
54
553)连续猜就需要用while
56 random="$((RANDOM%60))"
57 count=0
58 while true
59 do
60 ((count++))
61 read -p "请猜数字:" num
62 if [ $num -gt $random ]
63 then
64 echo "猜高了。"
65 elif [ $num -eq $random ]
66 then
67 echo "牛啊,猜对了,一共猜了${count}次。"
68 exit
69 else
70 echo "猜低了。"
71 fi
72 done
73
74Apache访问日志(access_2010-12-8.log),把日志中每行的访问字节数对应字段数字相加,计算出总的访问量。给出实现程序,请用while循环实现。(3分钟)
75
xxxxxxxxxx
281 until statement syntax
2until condition|true|false
3do
4 statement
5done
6
7#
8declare -i j=1
9declare -i i=1
10
11until [ $j -gt 9 ]; do
12 until [ $i -gt $j ]; do
13 echo -n -e "${i}X${j}=$[$i*$j]\t"
14 let i++
15 done
16 echo
17 let i=1
18 let j++
19done
20
21
22#
23read -p "Enter a user name: " username
24
25until who | grep "^$username" &> /dev/null; do
26 sleep 3
27done
28
select
xxxxxxxxxx
621select statement
2select variable in list
3do
4 statement
5done
6
7echo "Which car do you prefer?"
8select CAR in Benz Audi VolksWagen
9do
10 break
11done
12echo "You chose $CAR"
13
14
15
16select DAY in Mon Tue Wed Thu Fri Sat Sun
17do
18 case $DAY in
19 Mon)
20 echo "Today is Monday";;
21 Tue)
22 echo "Today is Tuesday";;
23 Wed)
24 echo "Today is Wednesday";;
25 Thu)
26 echo "Today is Thursday";;
27 Fri)
28 echo "Today is Friday";;
29 Sat|Sun)
30 echo "You can have a rest today";;
31 *)
32 echo "Unknown input ,exit now" && break;;
33 esac
34done
35
36
37
38 命令 说明
39break n 如果省略n表示跳出整个循环,n 表示跳出循环的层数
40continue n 如果省略n表示跳过本次循环,忽略本次循环的剩余代码,进入循环的下一次循环。n 表示退到第n层继续循环
41exit n 退出当前shell程序,n为上一次程序执行的状态返回值。n也可以省略,再下一个shell里可通过$?接收exit n的n值
42return n 用于在函数里,作为函数的返回值,用于判断函数执行是否正确。再下一个shell里可通过$?接收exit n的n值
43
44break[n]和continue[n]都是在循环语句中使用,break 结束整个循环,continue退出当次循环,进入下次循环。
45
46
47#
48declare -i i=0
49declare -i sum=0
50
51until [ $i -gt 100 ]; do
52 let i++
53 if [ $[$i%2] -eq 1 ]; then
54 continue
55 fi
56 let sum+=$i
57done
58
59echo "Even sum: $sum"
60
61break、continue在条件语句及循环语句(for、while、if等)中用于控制程序的走向,而exit则用于终止所有语句并退出当前脚本,除此之外,exit还可以返回上一次程序或命令的执行状态值给当前Shell;return类似exit,只不过return仅用于在函数内部返回函数执行的状态值。
62
xxxxxxxxxx
1241是函数的返回值,它返回值给调用者。
2
3函数调用和传参
4
5function test(){
6 local name="test" #仅在函数内生效
7 id="id_test" # 在函数内外都生效,不建议使用
8 echo "The test function \$1 is $1" #这里的$1是传入函数的参数
9 return 1
10}
11
12# 函数一定要先定义后调用
13test args
14test $1 #这里的$1是传入脚本的参数
15echo $? # 获取函数return的值
16echo ${id}
17# echo ${name} #获取不到
18
19其它脚本中调用函数
20
21. /path/to/func_filename
22source /path/to/func_filename
23test args
24test $1 #这里的$1是传入脚本的参数
25
26
27企业案例:通过脚本传参的方式,检查Web 网站URL是否正常。
28wget命令:
29 --spider 模拟爬虫
30 -q 安静访问
31 -o /dev/null 不输出
32 -T --timeout 超时时间
33 -t --tries 重试次数
34~]# wget --spider -T 5 -q -o /dev/null -t 2 www.baidu.com
35~]# echo $?
360
37curl命令:
38 -I 看响应头
39 -s 安静的
40 -o /dev/null 不输出
41 -w %{http_code} 返回状态码,200
42 -m 超时时间
43
44~]# curl www.baidu.com -s &>/dev/null
45~]# echo $?
460
47~]# curl -I -m 5 -s -w "%{http_code}\n" -o /dev/null www.baidu.com
48200
49
50
51不用函数的实现写法
52
53if [ $# -ne 1 ]
54 then
55 echo $"usage:$0 url"
56 exit 1
57fi
58wget --spider -q -o /dev/null --tries=1 -T 5 $1 #<==-T指定超时时间,这里的$1为脚本的参数。
59if [ $? -eq 0 ]
60 then
61 echo "$1 is yes."
62else
63 echo "$1 is no."
64fi
65高端专业的函数写法:
66
67cat checkurl.sh
68
69##############################################################
70# File Name: checkurl.sh
71# Version: V1.0
72# Author: oldboy
73# Organization: www.oldboyedu.com
74# Created Time : 2018-06-07 18:29:19
75# Description:
76##############################################################
77usage(){
78 echo "Usage:$0 url"
79 exit 1
80}
81checkurl(){
82 wget -q -o /dev/null -t 2 -T 5 $1
83 if [ $? -eq 0 ]
84 then
85 echo "$1 is ok"
86 else
87 echo "$1 is fail"
88 fi
89}
90main(){
91 if [ $# -ne 1 ]
92 then
93 usage
94 fi
95 checkurl $1
96}
97main $*
98
99[root@oldboy scripts]# cat 8_5_1.sh
100
101function usage() { #<==帮助函数
102 echo $"usage:$0 url"
103 exit 1
104}
105
106function check_url() { #<==检测URL函数。
107 wget --spider -q -o /dev/null --tries=1 -T 5 $1 #<==这里的$1就是函数传参。
108 if [ $? -eq 0 ]
109 then
110 echo "$1 is yes."
111 else
112 echo "$1 is no."
113 fi
114}
115
116function main() { #<==主函数。
117 if [ $# -ne 1 ] #<==如果传入的多个参数,则打印帮助函数,提示用户。
118 then
119 usage
120 fi
121 check_url $1 #<==接收函数的传参,即把结尾的$*传到这里。
122}
123main $* #<==这里的$*就是把命令行接收的所有参数作为函数参数传给函数内部,常用手法。
124
array
xxxxxxxxxx
501Shell数组的定义
2Shell数组的定义有多种方法,列举如下。
3方法1:用小括号将变量值括起来赋值给数组变量,每个变量值之间要用空格分隔。
4语法如下:
5array=(value1 value2 value3 ... )
6此为常用定义方法,需重点掌握。
7示例如下:
8~]# array=(1 2 3) #<==用小括号将数组内容赋值给数组变量,数组元素用“空格”分隔开。
9~]# echo ${array[*]} #<==输出上面定义的数组的所有元素值,注意语法。
101 2 3
11方法2:用小括号将变量值括起来,同时采用键值对的形式赋值。
12语法如下:
13array=([1]=one [2]=two [3]=three)
14此种方法为key-value键值对的形式,小括号里对应的数字为数组下标,等号后面的内容为下标对应的数组变量的值,此方法比较复杂,不推荐使用。
15示例如下:
16~]# array=([1]=one [2]=two [3]=three)
17~]# echo ${array[*]} #<==输出上面定义的数组的所有元素值。
18one two three
19~]# echo ${array[1]} #<==输出上面定义的数组的第一个元素值。
20one
21~]# echo ${array[2]} #<==输出上面定义的数组的第二个元素值。
22two
23~]# echo ${array[3]} #<==输出上面定义的数组的第三个元素值。
24three
25方法3:通过分别定义数组变量的方法来定义。
26语法如下:
27array[0]=a;array[1]=b;array[2]=c
28此种定义方法比较麻烦,不推荐使用。
29示例如下:
30~]# array[0]=a
31~]# array[1]=b
32~]# array[2]=c
33~]# echo ${array[0]}
34a
35方法4:动态地定义数组变量,并使用命令的输出结果作为数组的内容。
36语法为:
37array=($(命令))
38或
39array=(`命令`)
40示例如下:
41data]# mkdir /array/ -p
42data]# touch /array/{1..3}.txt
43data]# ls /array/
441.txt 2.txt 3.txt
45data]# array=($(ls /array))
46data]# echo ${array[*]}
471.txt 2.txt 3.txt
48说明:还可以使用declare -a array来定义数组类型,但是比较少这样用。
49
50
xxxxxxxxxx
1501Shell数组的打印及输出
21. 打印数组元素
3此为常用知识点,需重点掌握。示例如下:
4data]# array=(one two three)
5data]# echo ${array[0]}
6#<==打印单个数组元素用${数组名[下标]},当未指定数组下标时,数组的下标是从0开始。
7one
8data]# echo ${array[1]}
9two
10data]# echo ${array[2]}
11three
12data]# echo ${array[*]} #<==使用*或者@可以得到整个数组内容。
13one two three
14data]# echo ${array[@]} #<==使用*或者@可以得到整个数组内容。
15one two three
162. 打印数组元素的个数
17此为常用知识点,需重点掌握。示例如下:
18data]# echo ${array[*]} #<==使用*或者@可以得到整个数组内容。
19one two three
20data]# echo ${#array[*]} #<==用${#数组名[@或*]}可以得到数组长度,这和前文讲解的变量子串知识是一样的,因为数组也是变量,只不过是特殊的变量,因此也适合变量的子串替换等知识。
213
22data]# echo ${array[@]} #<==使用*或者@可以得到整个数组内容。
23one two three
24data]# echo ${#array[@]} #<==用${#数组名[@或*]}可以得到数组长度,这和前文讲解的变量子串知识是一样的,因为数组也是变量,只不过是特殊的变量,因此也适合变量的子串替换等知识。
253
263. 数组赋值
27此知识不常用,了解即可。可直接通过“数组名[下标] ”对数组进行引用赋值,如果下标不存在,自动添加新一个数组元素,如果下标存在就覆盖原来的值。
28示例如下:
29data]# array=(one two three)
30data]# echo ${array[*]}
31one two three
32data]# array[3]=four #<==增加下标为3的数组元素。
33data]# echo ${array[*]}
34one two three four
35data]# array[0]=oldboy
36data]# echo ${array[*]}
37oldboy two three four
38~]# array[0]=mei #<==修改数组元素。
39~]# echo ${array[@]}
40mei 2 3 4
414. 数组的删除
42因为数组本质上还是变量,因此可通过“unset 数组[下标]”清除相应的数组元素,如果不带下标,表示清除整个数组的所有数据。
43示例如下:
44data]# echo ${array[*]}
45oldboy two three four
46data]# unset array[1] #<==取消下标为1的数组元素。
47data]# echo ${array[*]} #<==打印输出后发现数组元素“two”,不见了。
48oldboy three four
49data]# unset array #<==删除整个数组。
50data]# echo ${array[*]}
51#<==没有任何内容了。
525. 数组内容的截取和替换
53这里和前文变量子串的替换是一样的,因为数组是特殊的变量。数组元素部分内容截取的示例如下:
54~]# array=(1 2 3 4 5)
55~]# echo ${array[@]:1:3} #<==从下标为1的元素开始截取,共取3个数组元素。
562 3 4
57data]# array=({a..z}) #<==将变量的结果赋值给数组变量。
58data]# echo ${array[@]}
59a b c d e f g h i j k l m n o p q r s t u v w x y z
60data]# echo ${array[@]:1:3} #<==从下标为1的元素开始截取,共取3个数组元素。
61b c d
62data]# echo ${array[@]:0:2} #<==从下标为0的元素开始截取,共取2个数组元素。
63a b
64数组元素部分内容的替换如下:
65data]# array=(1 2 3 1 1)
66data]# echo ${array[@]/1/b} #<==把数组中的1替换成b,原数组未被修改,和sed很像。
67b 2 3 b b
68提示:调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,可以看上面例子,重新定义数组。
69数组元素部分内容的删除如下:
70data]# array=(one two three four five)
71data]# echo ${array[@]}
72one two three four five
73data]# echo ${array[@]#o*} #<==从左边开始匹配最短的,并删除。
74ne two three four five
75data]# echo ${array1[@]##o*} #<==从左边开始匹配最长的,并删除。
76two three four five
77data]# echo ${array[@]%f*} #<==从右边开始匹配最短的,并删除。
78one two three
79data]# echo ${array[@]%%f*} #<==从右边开始匹配最长的,并删除。
80one two three
81提示:数组也是变量,因此也适合于前面讲解过的变量的子串处理的功能应用。
82数组的其他相关知识通过man bash然后搜Arrays来了解。
83
84
85范例:使用循环批量输出数组的元素。
86方法1:通过C语言型的for循环语句打印数组元素。
87
88array=(1 2 3 4 5)
89for((i=0;i<${#array[*]};i++)) #<==从数组的第一个小标0开始,循环数组的所有下标。
90do
91 echo ${array[i]} #<==打印数组元素。
92done
93方法2:通过普通for循环语句打印数组元素。
94
95array=(1 2 3 4 5)
96for n in ${array[*]} #<==${array[*]}表示输出数组所有元素,相当于列表数组元素。
97do
98 echo $n #<==这里就不是直接去数组里取元素了,而是变量n的值。
99done
100输出结果同方法1,此处略过。
101方法3:使用while循环语句打印数组元素。
102
103array=(1 2 3 4 5)
104i=0
105while ((i<${#array[*]}))
106do
107 echo ${array[i]}
108 ((i++))
109done
110输出结果同方法1,此处略过。
111
112范例:通过竖向列举法定义数组元素并批量打印。
113
114array=( #<==对于元素特别长的时候,例如URL地址,竖向列出来看起来舒服和规范。
115 oldboy
116 oldgirl
117 xiaoting
118 bingbing
119)
120for ((i=0; i<${#array[*]}; i++))
121do
122 echo "This is num $i,then content is ${array[$i]}"
123done
124echo ----------------------
125echo "array len:${#array[*]}"
126输出结果如下:
127This is num 0,then content is oldboy
128This is num 1,then content is oldgirl
129This is num 2,then content is xiaoting
130This is num 3,then content is bingbing
131----------------------
132array len:4
133范例:把命令结果作为数组元素定义并打印。
134准备数据:
135scripts]# mkdir -p /array/
136scripts]# touch /array/{1..3}.txt
137scripts]# ls /array/
1381.txt 2.txt 3.txt
139以下为开发脚本:
140
141dir=($(ls /array)) #<==把ls /array命令结果放数组里。
142for ((i=0; i<${#dir[*]}; i++)) #<==${#dir[*]}为数组的长度。
143do
144 echo "This is NO.$i,filename is ${dir[$i]}"
145done
146输出结果如下:
147This is NO.0,filename is 1.txt
148This is NO.1,filename is 2.txt
149This is NO.2,filename is 3.txt
150
xxxxxxxxxx
331(1)定义命令
2静态数组:
3array=(1 2 3)
4动态数组:
5array=($(ls))或array=(`ls`)
6给数组赋值:
7array[3]=4
8(2)打印命令
9打印所有元素:
10${array[@]}或${array[*]}
11打印数组长度:
12${#array[@]}或${#array[*]}
13打印单个元素:
14${array[i]} #<==i是数组下标。
15(3)循环打印的常用基本循环
16
17arr=(
18 10.0.0.11
19 10.0.0.22
20 10.0.0.33
21)
22#C语言for循环语法
23for ((i=0;i<${#arr[*]};i++))
24do
25 echo "${arr[$i]}"
26done
27echo ---------------
28#普通for循环语法
29for n in ${arr[*]}
30do
31 echo "$n"
32done
33
xxxxxxxxxx
3911范例:利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题)。
2I am oldboy teacher welcome to oldboy training class
3解答思路:
41)先把所有的单词放到数组里,然后依次进行判断。命令如下:
5array=(I am oldboy teacher welcome to oldboy training class)
62)对变量内容计算长度,这在前文已经讲解过了。常见方法有4种:
7scripts]# char=oldboy
8scripts]# echo $char|wc -L
96
10scripts]# echo ${#char}
116
12scripts]# expr length $char
136
14scripts]# echo $char|awk '{print length}'
156
16方法1:通过数组方法实现。
17arr=(I am oldboy teacher welcome to oldboy training class)
18for ((i=0;i<${#arr[*]};i++))
19do
20 if [ ${#arr[$i]} -lt 6 ]
21 then
22 echo "${arr[$i]}"
23 fi
24done
25echo -----------------------
26for word in ${arr[*]}
27do
28 if [ `expr length $word` -lt 6 ];then
29 echo $word
30 fi
31done
32说明:本例给出了两种for循环语法打印数组元素的方法。
33方法2:使用for循环列举取值列表法
34for word in I am oldboy teacher welcome to oldboy training class #<==看起来有点low吧。
35do
36 if [ `echo $word|wc -L` -lt 6 ];then
37 echo $word
38 fi
39done
40
41chars="I am oldboy teacher welcome to oldboy training class" #<==定义字符串也可以。
42for word in $chars
43do
44 if [ `echo $word|wc -L` -lt 6 ];then
45 echo $word
46 fi
47done
48方法3:通过awk循环实现。
49scripts]# chars="I am oldboy teacher welcome to oldboy training class"
50scripts]# echo $chars|awk '{for(i=1;i<=NF;i++) if(length($i)<=6)print $i}'
51几种方法的输出结果统一为:
52I
53am
54oldboy
55to
56oldboy
57class
58范例:批量检查多个网站地址是否正常
59要求:
601)使用Shell数组方法实现,检测策略尽量模拟用户访问。
612)每10秒钟做一次所有的检测,无法访问的输出报警。
623)待检测的地址如下。
63http://blog.oldboyedu.com
64http://blog.etiantian.org
65http://oldboy.blog.51cto.com
66http://10.0.0.7
67解题思路:
681)把URL定义成数组,形成函数。
692)编写URL检查脚本函数,传入数组的元素,即URL。
703)组合实现整个案例,编写main主函数(即执行函数),每隔10秒检查一次。
71下面的参考答案采用了Shell数组方法,同时检测多个URL是否正常,并给出专业的展效果
72
73# this script is created by oldboy.
74# e_mail:31333741@qq.com
75# function:case example
76# version:1.3
77. /etc/init.d/functions
78check_count=0
79url_list=( #<==定义检测的URL数组,包含多个URL地址。
80http://blog.oldboyedu.com
81http://blog.etiantian.org
82http://oldboy.blog.51cto.com
83http://10.0.0.7
84)
85
86function wait() #<==定义3,2,1倒计时函数。
87{
88 echo -n '3秒后,执行检查URL操作.';
89 for ((i=0;i<3;i++))
90 do
91 echo -n ".";sleep 1
92 done
93 echo
94}
95function check_url() #<==定义检测URL的函数。
96{
97 wait #<==执行倒计时函数。
98 for ((i=0; i<`echo ${#url_list[*]}`; i++)) #<==循环数组元素。
99 do
100 wget -o /dev/null -T 3 --tries=1 --spider ${url_list[$i]} >/dev/null 2>&1 #<==检测是否可以访问数组元素的地址。
101 if [ $? -eq 0 ] #<==如果返回值为0,表示访问成功。
102 then
103 action "${url_list[$i]}" /bin/true #<==优美的显示成功结果。
104 else
105 action "${url_list[$i]}" /bin/false #<==优美的显示失败结果。
106 fi
107 done
108 ((check_count++)) #<==检测次数加1。
109}
110main(){ #<==定义主函数。
111 while true #<==开启一个持续循环。
112 do
113 check_url #<==加载检测url的函数。
114 echo "-------check count:${check_count}---------"
115 sleep 10 #<==间歇10秒。
116 done
117}
118main #<==优美的显示成功结果,调用主函数运行程序。
119执行结果如图所示。
120检测数组内URL输出的专业效果图
121提示:实际使用时,一些基础的函数脚本(例如:加颜色的函数)是放在函数文件里的(例如:放在/etc/init.d/functions里,与执行的脚本内容部分分离,看起来更清爽,大型的语言程序都是这样开发的),另外,特别注意wget命令后要接重试次数--tries参数,否则检查时会卡住。
122
123范例:开发一个守护进程脚本,每30秒监控MySQL主从复制是否异常(包括不同步以及延迟),如果异常,则发送短信并发送邮件给管理员存档(此为生产实战案例)。
124提示:如果没主从复制的环境,可以把下面的文本放到文件里读取来模拟主从复制状态:
125*************************** 1. row ***************************
126 Slave_IO_State: Waiting for master to send event
127 Master_Host: 10.0.0.51
128 Master_User: rep
129 Master_Port: 3306
130 Connect_Retry: 60
131 Master_Log_File: mysql-bin.000013
132 Read_Master_Log_Pos: 502547
133 Relay_Log_File: relay-bin.000013
134 Relay_Log_Pos: 251
135 Relay_Master_Log_File: mysql-bin.000013
136 Slave_IO_Running: Yes #<==IO线程状态必须为Yes
137 Slave_SQL_Running: Yes #<==SQL线程状态必须为Yes
138 Replicate_Do_DB:
139 Replicate_Ignore_DB: mysql
140 Replicate_Do_Table:
141 Replicate_Ignore_Table:
142 Replicate_Wild_Do_Table:
143 Replicate_Wild_Ignore_Table:
144 Last_Errno: 0
145 Last_Error:
146 Skip_Counter: 0
147 Exec_Master_Log_Pos: 502547
148 Relay_Log_Space: 502986
149 Until_Condition: None
150 Until_Log_File:
151 Until_Log_Pos: 0
152 Master_SSL_Allowed: No
153 Master_SSL_CA_File:
154 Master_SSL_CA_Path:
155 Master_SSL_Cert:
156 Master_SSL_Cipher:
157 Master_SSL_Key:
158 Seconds_Behind_Master: 0 #<==和主库比同步延迟的秒数,这个参数很重要。
159Master_SSL_Verify_Server_Cert: No
160 Last_IO_Errno: 0
161 Last_IO_Error:
162 Last_SQL_Errno: 0
163 Last_SQL_Error:
164解题思路:
1651)判断主从复制是否异常,主要就是检测如下参数对应的值是否和如下一致。
166 Slave_IO_Running: Yes #<==IO线程状态必须为Yes。
167 Slave_SQL_Running: Yes #<==SQL线程状态必须为Yes。
168 Seconds_Behind_Master: 0 #<==和主库比同步延迟的秒数,这个参数很重要。
1692)读取状态数据或状态文件,然后取出对应值,和正确时的值进行比对,如果不符合就表示故障了,即调用报警脚本报警。
1703)为了更专业,还可以在当主从不同步时,查看相应错误号,判断对应错误号以进行自动恢复主从复制故障(这些错误号也可以通过配置文件里配置参数实现自动忽略故障)。
171以下为参考答案。
172首先给出模拟数据(注意,使用时要去掉中文注释)。
173[root@oldboy scripts]# cat slave.log
174*************************** 1. row ***************************
175 Slave_IO_State: Waiting for master to send event
176 Master_Host: 10.0.0.51
177 Master_User: rep
178 Master_Port: 3306
179 Connect_Retry: 60
180 Master_Log_File: mysql-bin.000013
181 Read_Master_Log_Pos: 502547
182 Relay_Log_File: relay-bin.000013
183 Relay_Log_Pos: 251
184 Relay_Master_Log_File: mysql-bin.000013
185 Slave_IO_Running: Yes
186 Slave_SQL_Running: Yes
187 Replicate_Do_DB:
188 Replicate_Ignore_DB: mysql
189 Replicate_Do_Table:
190 Replicate_Ignore_Table:
191 Replicate_Wild_Do_Table:
192 Replicate_Wild_Ignore_Table:
193 Last_Errno: 0
194 Last_Error:
195 Skip_Counter: 0
196 Exec_Master_Log_Pos: 502547
197 Relay_Log_Space: 502986
198 Until_Condition: None
199 Until_Log_File:
200 Until_Log_Pos: 0
201 Master_SSL_Allowed: No
202 Master_SSL_CA_File:
203 Master_SSL_CA_Path:
204 Master_SSL_Cert:
205 Master_SSL_Cipher:
206 Master_SSL_Key:
207 Seconds_Behind_Master: 0
208Master_SSL_Verify_Server_Cert: No
209 Last_IO_Errno: 0
210 Last_IO_Error:
211 Last_SQL_Errno: 0
212 Last_SQL_Error:
213然后开发脚本,开发脚本有多种方法,下面分别给出。
214方法1:
215scripts]# awk -F ': ' '/_Running|_Behind/{print $NF}' slave.log
216#<==获取所有复制相关的状态值。
217Yes
218Yes
2190
220[root@oldboy scripts]# cat 13_6_1.sh
221count=0
222status=($(awk -F ': ' '/_Running|_Behind/{print $NF}' slave.log)) #<==获取所有复制相关的状态值赋值给数组status。
223for((i=0;i<${#status[*]};i++)) #<==循环数组元素。
224do
225 if [ "${status[${i}]}" != "Yes" -a "${status[${i}]}" != "0" ] #<==如果数组元素值不为Yes并且不为0任意一个,那就表示复制出故障了。
226 then
227 let count+=1 #<==错误数加1。
228 fi
229done
230if [ $count -ne 0 ];then #<==只要错误数不等于0,就表示状态值肯定有有问题的。
231 echo "mysql replcation is failed" #<==提示复制出现问题。
232else
233 echo "mysql replcation is sucess" #<==否则提示复制正常。
234fi
235说明:本答案是为了引导读者,没有加每30秒。
236测试结果如下:
237scripts]# sh 13_6_1.sh
238mysql replcation is sucess
239scripts]# sed -i 's#Slave_IO_Running: Yes#Slave_IO_Running: No#g' slave.log #<==提模拟IO线程故障。
240scripts]# sh 13_6_1.sh
241mysql replcation is failed
242方法2:本方法和方法1实现的功能差不多,但是开发手法就更高大上一些。
243
244CheckDb(){
245 count=0
246status=($(awk -F ': ' '/_Running|_Behind/{print $NF}' slave.log))
247for((i=0;i<${#status[*]};i++))
248do
249 if [ "${status[${i}]}" != "Yes" -a "${status[${i}]}" != "0" ]
250 then
251 let count+=1
252 fi
253done
254if [ $count -ne 0 ];then
255 echo "mysql replcation is failed"
256 return 1
257else
258 echo "mysql replcation is sucess"
259 return 0
260fi
261}
262main(){
263while true
264do
265 CheckDb
266 sleep 3
267done
268}
269main
270测试结果如下:
271scripts]# sed -i 's#Slave_IO_Running: No#Slave_IO_Running: Yes#g' slave.log #<==模拟IO线程恢复正常。
272scripts]# sh 13_6_2.sh
273mysql replcation is sucess
274mysql replcation is sucess
275mysql replcation is sucess
276^C
277scripts]# sed -i 's#Slave_IO_Running: Yes#Slave_IO_Running: No#g' slave.log #<==提示复制出现问题。
278scripts]# sh 13_6_2.sh
279mysql replcation is failed
280mysql replcation is failed
281^C
282说明:本答案还是没有完全满足题意,例如,报警短信和邮件没有开发。
283方法3(此为企业生产正式检查脚本):
284
285###########################################
286# this script function is :
287# check_mysql_slave_replication_status
288# USER YYYY-MM-DD - ACTION
289# oldboy 2009-02-16 - Created
290############################################
291path=/server/scripts #<==定义脚本存放路径,大家注意这个规范。
292MAIL_GROUP="1111@qq.com 2222@qq.com" #<==邮件列表,以空格隔开。
293PAGER_GROUP="18600338340 18911718229" #<==手机列表,以空格隔开。
294LOG_FILE="/tmp/web_check.log" #<==日志路径。
295USER=root #<==数据库用户。
296PASSWORD=oldboy123 #<==用户密码。
297PORT=3307 #<==端口。
298MYSQLCMD="mysql -u$USER -p$PASSWORD -S /data/$PORT/mysql.sock" #<==登录数据库命令。
299error=(1008 1007 1062) #<==可以忽略的主从复制错误号。
300RETVAL=0
301[ ! -d "$path" ] && mkdir -p $path
302function JudgeError(){ #<==定义判断主从复制错误的函数。
303 for((i=0;i<${#error[*]};i++))
304 do
305 if [ "$1" == "${error[$i]}" ] #<==如果传入的错误号和数组里的元素匹配,则执行then后命令。
306 then
307 echo "MySQL slave errorno is $1,auto repairing it."
308 $MYSQLCMD -e "stop slave;set global sql_slave_skip_counter=1;start slave;" #<==自动修复。
309 fi
310 done
311 return $1
312}
313function CheckDb(){ #<==定义检查数据库主从复制状态的函数。
314status=($(awk -F ': ' '/_Running|Last_Errno|_Behind/{print $NF}' slave.log))
315 expr ${status[3]} + 1 &>/dev/null #<==这个是延迟状态值,进行是否为数字判断。
316 if [ $? -ne 0 ];then #<==如果不为数字。
317 status[3]=300 #<==赋值300,当数据库出现复制故障时,延迟这个状态值有可能是NULL,即非数字。
318 fi
319 if [ "${status[0]}" == "Yes" -a "${status[1]}" == "Yes" -a ${status[3]} -lt 120 ]
320 #<==两个线程都为Yes,并且延迟小于120秒,即认为复制状态是正常的。
321 then
322 #echo "Mysql slave status is ok"
323 return 0 #<==返回0。
324 else
325 #echo "mysql replcation is failed"
326 JudgeError ${status[2]} #<==否则将错误号${status[2]},传入JudgeError函数,判断错误号是否可以自动修复。
327 fi
328}
329function MAIL(){ #<==定义邮件函数,在范例11_13讲过此函数。
330local SUBJECT_CONTENT=$1 #<==函数的第一个传参赋值给主题变量。
331for MAIL_USER in `echo $MAIL_GROUP` #<==遍历邮件列表。
332do
333 mail -s "$SUBJECT_CONTENT " $MAIL_USER <$LOG_FILE #<==发邮件。
334done
335}
336function PAGER(){#<==定义手机函数,在范例11_13讲过此函数。
337 for PAGER_USER in `echo $PAGER_GROUP` #<==遍历手机列表。
338 do
339 TITLE=$1 #<==函数的第一个传参赋值给主题变量。
340 CONTACT=$PAGER_USER #<==手机号赋值给CONTACT变量。
341 HTTPGW=http://oldboy.sms.cn/smsproxy/sendsms.action #<==发短信地址,这个地址需要用户付费购买的,如果免费的就得用139,微信替代了。
342 #send_message method1
343 curl -d cdkey=5ADF-EFA -d password=OLDBOY -d phone=$CONTACT -d message="$TITLE[$2]" $HTTPGW
344#<==发送短信报警的命令。cdkey是购买短信网关时,售卖者给的,password是密码,也是售卖者给的。
345 done
346}
347function SendMsg(){
348 if [ $1 -ne 0 ] #<==传入$1,如果不为0表示复制有问题,这里的$1即CheckDb里的返回值(用检测失败的次数作为返回值),在后文主函数main执行时调用SendMsg传参时传进来。
349 then
350 RETVAL=1
351 NOW_TIME=`date +"%Y-%m-%d %H:%M:%S"`#<==报警时间。
352 SUBJECT_CONTENT="mysql slave is error,errorno is $2,${NOW_TIME}."#<==报警主题。
353 echo -e "$SUBJECT_CONTENT"|tee $LOG_FILE #<==输出信息,并记录到日志。
354 MAIL $SUBJECT_CONTENT #<==发邮件报警,$SUBJECT_CONTENT作为函数参数传给MAIL函数体的$1。
355 PAGER $SUBJECT_CONTENT $NOW_TIME #<==发短信报警,$SUBJECT_CONTENT作为函数参数传给MAIL函数体的$1,$NOW_TIME作为函数体传给$2。
356 else
357 echo "Mysql slave status is ok"
358 RETVAL=0 #<==以0作为返回值。
359 fi
360 return $RETVAL
361}
362function main(){
363while true
364do
365 CheckDb
366 SendMsg $? #<==传入第一个参数$?,即CheckDb里的返回值(用检测失败的次数作为返回值)。
367 sleep 300
368done
369}
370main
371
372
373下面列举的知识点是老男孩要求所有学生必会的,这些脚本知识点中的很多内容不仅仅涉及脚本知识,还有系统命令、大量网络服务的知识,这些都需要读者了解和掌握,Shell编程仅仅是其中的一部分内容。
374作为一个合格运维人员,需要掌握的脚本列表如下:
3751)系统及各类服务的监控脚本,例如:文件、内存、磁盘、端口,URL监控报警等。
3762)监控网站目录下文件是否被篡改,以及站点目录批量被篡改后如何批量恢复的脚本。
3773)各类服务Rsync、Nginx、MySQL等的启动及停止专业脚本(使用chkconfig管理)。
3784)MySQL主从复制监控报警以及自动处理不复制故障的脚本。
3795)一键配置MySQL多实例、一键配置MySQL主从部署脚本。
3806)监控HTTP/MySQL/Rsync/NFS/Memcached等服务是否异常的生产脚本。
3817)一键软件安装及优化的脚本,比如LANMP、Linux一键优化,一键数据库安装、优化等。
3828)MySQL多实例启动脚本,分库、分表自动备份脚本。
3839)根据网络连接数以及根据Web日志PV封IP的脚本。
38410)监控网站的PV以及流量,并且对流量信息进行统计的脚本。
38511)检查Web服务器多个URL地址是否异常的脚本,要可以批量处理且通用。
38612)系统的基础优化一键优化的脚本。
38713)TCP连接状态及IP统计报警脚本。
38814)批量创建用户并设置随机8位密码的脚本。
389
390注:到此shell编程重要知识完,重在思路和多练习多实践并且熟悉Linux上的常用命令。
391
xxxxxxxxxx
281批量生成随机字符文件名
2成随机数的 7 种方法:
31)echo $RANDOM 范围是 0-32767
42)openssl rand -base64 100
53)date +%s%N
64)head /dev/urandom|cksum
75)uuidgen
86)cat /proc/sys/kernel/random/uuid
97)mkpasswd(yum install expect -y)
10mkpasswd -l 20 -d 10 -C 5 -c 3 -s 2
11-l 长度
12-d 数字
13-c 小写字母
14-C 大写字母
15-s 特殊字符
16
17echo "OLDBOY$RANDOM"|md5sum|tr "0-9" "m-z"|cut -c 2-11
18cat exam1.sh
19
20path=/data/testing
21[ -d $path ]||mkdir -p $path
22for n in {1..10}
23do
24 random=`echo "MEI$RANDOM"|md5sum|tr "0-9" "m-z"|cut -c 2-11`
25 touch $path/${random}_mei.txt
26done
27
28
xxxxxxxxxx
231批量改名
2将exam1中创建的文件中,文件名中mei字串改为test并将扩展名换为大写。
3先改一个:
4[root@foundation testing]# file=bdscsamccb_mei.txt
5[root@foundation testing]# echo ${file/mei.txt/test.TXT}
6bdscsamccb_test.TXT
7[root@foundation testing]# mv $file `echo ${file/mei.txt/test.TXT}`
8[root@foundation testing]# ls `echo ${file/mei.txt/test.TXT}` -l
9-rw-r--r--. 1 root root 0 Feb 4 15:50 bdscsamccb_test.TXT
10
11for循环
12
13dir=/data/testing
14for file in `ls $dir`;do
15 mv ${dir}/${file} `echo ${dir}\/${file/mei.txt/test.TXT}`
16done
17
18拼接
19[root@foundation testing]# ls *.TXT|awk -F "test.TXT" '{print "mv",$0,$1"mei.txt"}'|bash
20rename命令
21[root@foundation testing]# rename "mei.txt" "test.HTML" *.txt
22
23
xxxxxxxxxx
681批量创建特殊要求的用户
2用户mei01-mei10,并设置随机密码
3生成01-10
4echo {01..10}
5seq -w 10
6
7生成随机密码
8openssl rand -base64 100
9
10为用户设置密码
11echo "password" |passwd --stdin username
12chpasswd设置密码
13文件要满足下面格式
14username:passwd
15username:passwd
16
17使用循环
18exam]# cat exam3_1.sh
19
20for n in {1..10};do
21 pass=`openssl rand -base64 10`
22 useradd mei$n
23 echo $pass|passwd --stdin mei$n
24 echo -e "mei$n\t$passwd" >>./exam3_1.codebook
25done
26
27exam]# cat exam3_2.sh
28
29for n in `seq -w 11 15`;do
30 pass=`openssl rand -base64 10`
31 useradd mei$n
32 echo "mei$n:$pass" >>./exam3_2.codebook
33done
34chpasswd < ./exam3_2.codebool
35
36exam]# cat exam3_3.sh
37
38. /etc/init.d/functions
39if [ $UID -ne 0 ];then
40
41. /etc/init.d/functions
42if [ $UID -ne 0 ];then
43 echo -e "Permission denied\nneed account root exec the $0"
44 exit 1
45fi
46
47for n in {16..20};do
48 pass=`openssl rand -base64 10`
49 if [ `grep -w "mei$n" /etc/passwd |wc -l` -eq 0 ];then
50 useradd mei$n & >/dev/null &&\
51 echo $pass|passwd --stdin mei$n &>/dev/null &&\
52 echo -e "mei$n\t$pass" >>./exam3_3.codebook &&\
53 action "create mei$n user seccessful." /bin/true
54 else
55 action "create mei$n user false." /bin/false
56 fi
57done
58注意:如果使用循环,那么可以使用命令拼接的方式拼接出整个创建用户和设置密码的过程。
59
60echo stu{01..10}|tr " " "\n"|sed -r 's#(.*)#useradd \1 ; pass=$((RANDOM+10000000)); echo "$pass"|passwd --stdin \1; echo -e "\1 \t `echo "$pass"`">>/tmp/oldboy.log#g'|bash
61
62echo stu{11..12}|xargs -n1 useradd ;echo stu{11..12}:`cat /dev/urandom|tr -dc 0-9|fold -w8|head -1`|xargs -n1|tee -a pass.txt|chpasswd
63
64echo stu{21..30} | tr ' ' '\n' | sed -e 's/^/useradd /' -e 's/\(stu[0-9]\{2\}\)$/\1 \&\& echo "\1:`echo $[$RANDOM**3] | cut -c1-8`" | tee -a userInfo.txt | cut -d: -f2 | passwd --stdin \1/'|bash
65
66echo stu{01..10} |tr ' ' '\n'|sed -rn 's@^(.*)$@useradd \1 ; echo $RANDOM|md5sum|cut -c 1-8 >/data/\1;cat /data/\1|passwd --stdin \1@gp'|bash
67
68
xxxxxxxxxx
181扫描网络中存活的主机
2ping -c 2 -i 1 -w 3 172.25.0.55
3arping 172.25.0.55
4nmap -sP 172.25.0.0/24
5
6
7network="172.25.0."
8for n in {1..254};do
9 {
10 if `ping -c 1 -w 3 ${network}${n}` &>/dev/null
11 then
12 echo -e "${network}${n} is \e[40;32;1mup\e[0m"
13 else
14 echo -e "${network}${n} is \e[40;33;1mdown\e[0m"
15 fi
16 } &
17done
18
xxxxxxxxxx
2991解决DOS攻击
2写一个Shell脚本解决DOS攻击生产案例。
3请根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100(读者根据实际情况设定),即调用防火墙命令封掉对应的IP。
4
5封IP:iptables -I INPUT -s IP地址-j DROP。
6web日志或网络连接数:日志文件,netstat -an|grep -i EST>netstat.log,排序去重。
7判断pv或者链接数大于100,取出Ip让后封。
8netstat.log日志内容模拟
9Active Internet connections (servers and established)
10Proto Recv-Q Send-Q Local Address Foreign Address State
11tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
12tcp 0 0 115.29.49.213:80 117.136.27.254:13779 SYN_RECV
13tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
14tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
15tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
16tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
17tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
18tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
19tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
20tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
21tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
22tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
23tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
24tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
25tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
26tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
27tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
28tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
29tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
30tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
31tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
32tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
33tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
34tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
35tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
36tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
37tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
38tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
39tcp 0 0 115.29.49.213:80 113.97.117.157:1847 SYN_RECV
40tcp 0 0 115.29.49.213:80 117.136.40.20:19594 SYN_RECV
41tcp 0 0 115.29.49.213:80 117.136.40.20:19595 SYN_RECV
42tcp 0 0 115.29.49.213:80 121.236.219.69:45363 SYN_RECV
43tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN
44tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
45tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
46tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
47tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
48tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
49tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
50tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
51tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
52tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
53tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
54tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
55tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
56tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
57tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
58tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
59tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
60tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
61tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
62tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
63tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
64tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
65tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
66tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
67tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
68tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
69tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
70tcp 0 0 115.29.49.213:80 123.163.178.32:3009 ESTABLISHED
71tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
72tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
73tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
74tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
75tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
76tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
77tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
78tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
79tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
80tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
81tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
82tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
83tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
84tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
85tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
86tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
87tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
88tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
89tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
90tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
91tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
92tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
93tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
94tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
95tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
96tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
97tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
98tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
99tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
100tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
101tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
102tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
103tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
104tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
105tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
106tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
107tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
108tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
109tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
110tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
111tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
112tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
113tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
114tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
115tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
116tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
117tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
118tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
119tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
120tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
121tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
122tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
123tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
124tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
125tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
126tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
127tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
128tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
129tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
130tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
131tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
132tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
133tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
134tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
135tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
136tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
137tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
138tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
139tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
140tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
141tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
142tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
143tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
144tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
145tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
146tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
147tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
148tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
149tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
150tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
151tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
152tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
153tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
154tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
155tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
156tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
157tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
158tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
159tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
160tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
161tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
162tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
163tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
164tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
165tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
166tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
167tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
168tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
169tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
170tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
171tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
172tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
173tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
174tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
175tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
176tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
177tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
178tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
179tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
180tcp 0 0 115.29.49.213:80 117.136.1.202:21158 TIME_WAIT
181tcp 0 0 115.29.49.213:80 220.191.224.154:48550 ESTABLISHED
182tcp 0 0 115.29.49.213:80 183.32.61.109:5600 ESTABLISHED
183tcp 0 0 115.29.49.213:80 27.17.23.22:51256 FIN_WAIT2
184tcp 0 0 115.29.49.213:80 218.242.161.183:50519 FIN_WAIT2
185tcp 0 0 115.29.49.213:80 223.104.12.101:49900 TIME_WAIT
186tcp 0 0 115.29.49.213:80 140.206.64.90:62291 TIME_WAIT
187tcp 0 0 115.29.49.213:80 120.237.97.10:54195 ESTABLISHED
188tcp 0 0 115.29.49.213:80 49.80.146.230:13453 FIN_WAIT2
189tcp 0 0 115.29.49.213:80 113.104.25.50:56714 FIN_WAIT2
190tcp 0 0 115.29.49.213:80 101.226.89.193:41639 ESTABLISHED
191tcp 0 0 115.29.49.213:80 119.147.225.185:58321 TIME_WAIT
192tcp 0 0 115.29.49.213:80 54.183.177.237:64129 TIME_WAIT
193tcp 0 0 115.29.49.213:80 120.198.202.48:41960 ESTABLISHED
194tcp 0 1 115.29.49.213:80 119.127.188.242:38843 FIN_WAIT1
195tcp 0 0 115.29.49.213:34081 223.4.9.70:80 TIME_WAIT
196tcp 0 0 115.29.49.213:80 58.223.4.14:46716 FIN_WAIT2
197tcp 0 0 115.29.49.213:80 122.90.74.255:12177 FIN_WAIT2
198tcp 0 0 115.29.49.213:80 59.53.166.165:62253 ESTABLISHED
199tcp 0 0 115.29.49.213:80 219.133.40.13:34113 ESTABLISHED
200tcp 0 0 115.29.49.213:80 222.175.140.230:29902 TIME_WAIT
201tcp 0 0 115.29.49.213:80 54.77.101.105:49967 TIME_WAIT
202tcp 0 0 115.29.49.213:80 54.207.37.100:63364 TIME_WAIT
203tcp 0 0 115.29.49.213:80 125.118.62.149:61840 FIN_WAIT2
204tcp 0 0 115.29.49.213:80 112.117.173.124:50367 ESTABLISHED
205tcp 0 0 115.29.49.213:80 120.194.52.156:2752 FIN_WAIT2
206tcp 0 0 115.29.49.213:80 114.106.68.5:54231 ESTABLISHED
207tcp 0 0 115.29.49.213:80 27.154.82.136:3013 FIN_WAIT2
208tcp 0 0 115.29.49.213:80 182.245.82.46:55306 FIN_WAIT2
209tcp 0 0 115.29.49.213:80 117.92.15.157:29926 TIME_WAIT
210tcp 0 0 115.29.49.213:80 163.179.63.118:62371 ESTABLISHED
211tcp 0 777 115.29.49.213:80 106.59.15.116:1673 ESTABLISHED
212tcp 0 777 115.29.49.213:80 117.22.215.8:1382 ESTABLISHED
213tcp 0 0 115.29.49.213:80 114.217.182.123:51960 TIME_WAIT
214tcp 0 0 115.29.49.213:80 118.242.18.177:24615 ESTABLISHED
215tcp 0 0 115.29.49.213:80 220.191.224.154:23380 TIME_WAIT
216tcp 0 0 115.29.49.213:80 119.78.240.118:59230 FIN_WAIT2
217tcp 0 0 115.29.49.213:80 218.83.11.138:52739 TIME_WAIT
218tcp 0 0 115.29.49.213:80 122.70.113.17:57809 TIME_WAIT
219tcp 0 0 115.29.49.213:80 121.235.160.76:2487 TIME_WAIT
220tcp 0 0 115.29.49.213:80 111.175.68.97:49920 TIME_WAIT
221tcp 0 1 115.29.49.213:80 221.137.78.206:54593 FIN_WAIT1
222tcp 0 0 115.29.49.213:80 119.121.180.245:14524 TIME_WAIT
223tcp 0 0 115.29.49.213:80 123.151.42.52:55816 ESTABLISHED
224tcp 0 0 115.29.49.213:80 120.192.146.19:26133 FIN_WAIT2
225tcp 0 0 115.29.49.213:80 113.107.56.233:45496 TIME_WAIT
226tcp 0 1 115.29.49.213:80 119.249.255.140:1664 FIN_WAIT1
227tcp 0 0 115.29.49.213:80 222.132.131.91:5451 ESTABLISHED
228tcp 0 0 115.29.49.213:80 183.32.61.109:5712 FIN_WAIT2
229tcp 0 52 115.29.49.213:22 119.2.28.4:13185 ESTABLISHED
230tcp 0 0 115.29.49.213:80 221.179.140.171:48647 TIME_WAIT
231tcp 0 0 115.29.49.213:80 111.161.61.49:60865 ESTABLISHED
232tcp 0 0 115.29.49.213:80 58.247.119.17:64369 TIME_WAIT
233tcp 0 0 115.29.49.213:80 121.35.208.125:50139 FIN_WAIT2
234tcp 0 0 115.29.49.213:80 118.242.18.177:24619 ESTABLISHED
235tcp 0 0 115.29.49.213:80 111.17.45.226:5492 TIME_WAIT
236tcp 0 0 115.29.49.213:80 114.250.252.127:50802 TIME_WAIT
237tcp 0 0 115.29.49.213:80 49.80.146.230:13424 TIME_WAIT
238tcp 0 0 115.29.49.213:80 113.241.77.56:18509 TIME_WAIT
239tcp 0 0 115.29.49.213:80 101.226.61.186:57302 ESTABLISHED
240tcp 0 0 115.29.49.213:80 59.38.233.215:18224 FIN_WAIT2
241tcp 0 0 115.29.49.213:80 222.70.73.234:52968 FIN_WAIT2
242tcp 0 0 115.29.49.213:80 114.100.142.6:3171 TIME_WAIT
243tcp 0 0 115.29.49.213:80 27.18.159.160:50095 TIME_WAIT
244tcp 0 0 115.29.49.213:80 122.64.91.155:35708 ESTABLISHED
245tcp 0 0 115.29.49.213:80 116.90.81.14:52978 TIME_WAIT
246tcp 0 0 115.29.49.213:80 124.227.212.140:38460 ESTABLISHED
247tcp 0 0 115.29.49.213:80 223.242.103.128:3997 TIME_WAIT
248tcp 0 0 115.29.49.213:80 113.116.147.94:50073 ESTABLISHED
249tcp 0 0 115.29.49.213:80 112.117.173.124:50366 TIME_WAIT
250tcp 0 0 115.29.49.213:80 122.227.191.174:4833 FIN_WAIT2
251tcp 0 0 115.29.49.213:80 42.95.73.152:51472 ESTABLISHED
252tcp 0 0 115.29.49.213:80 58.215.136.140:56794 TIME_WAIT
253tcp 0 0 115.29.49.213:80 116.90.81.14:52974 TIME_WAIT
254tcp 0 0 115.29.49.213:80 223.100.156.53:59779 TIME_WAIT
255tcp 0 0 115.29.49.213:80 125.112.122.240:44893 FIN_WAIT2
256tcp 0 0 115.29.49.213:80 14.211.169.36:26342 TIME_WAIT
257tcp 0 0 115.29.49.213:80 114.250.252.127:50809 TIME_WAIT
258tcp 0 0 115.29.49.213:80 14.157.228.55:3184 FIN_WAIT2
259tcp 0 0 115.29.49.213:80 112.113.160.225:3029 TIME_WAIT
260tcp 0 0 115.29.49.213:80 14.17.11.196:33403 ESTABLISHED
261tcp 0 0 115.29.49.213:80 36.249.78.78:2615 FIN_WAIT2
262tcp 0 0 115.29.49.213:80 114.105.192.151:1312 ESTABLISHED
263tcp 0 0 115.29.49.213:80 118.242.18.177:24616 FIN_WAIT2
264tcp 0 0 115.29.49.213:80 27.191.14.232:50272 FIN_WAIT2
265tcp 0 0 115.29.49.213:80 119.187.139.167:1779 FIN_WAIT2
266tcp 0 0 115.29.49.213:80 218.75.147.14:5195 TIME_WAIT
267tcp 0 0 115.29.49.213:80 1.204.201.226:12694 ESTABLISHED
268
269
270awk '{S[$1]++}END{for(key in S) print S[key],key}' access_2020-1-8.log|sort -rn|head >/tmp/ip.log
271while read line
272do
273ip=`echo $line|awk '{print $2}'`
274count=`echo $line|awk '{print $1}'`
275if [ $count -gt 100 -a `grep "$ip" /tmp/drop.log|wc -l` -lt 1 ]
276then
277iptables -I INPUT -s $ip -j DROP &&\
278echo "$ip" >>/tmp/drop.log
279else
280echo "$ip" >>/tmp/accept.log
281fi
282done</tmp/ip.log
283
284
285awk '/ESTAB/{print $0}' netstat.log |awk -F "[ :]+" '{print $(NF-3)}'|sort|uniq -c|sort -rn|head >
286/tmp/ip.log
287while read line
288do
289 ip=`echo $line|awk '{print $2}'`
290 count=`echo $line|awk '{print $1}'`
291 if [ $count -gt 10 -a `grep "$ip" /tmp/drop.log|wc -l` -lt 1 ]
292 then
293 iptables -I INPUT -s $ip -j DROP &&\
294 echo "$ip" >>/tmp/drop.log
295 else
296 echo "$ip" >>/tmp/accept.log
297 fi
298done</tmp/ip.log
299
xxxxxxxxxx
171数据库分库备份脚本
2常规备份
3mysqldump -B test mei|gzip >bak.sql.gz
4分库备份:
5mysqldump -B mei|gzip >bak.sql.gz
6mysqldump -B test|gzip >bak.sql.gz
7
8
9path=/backup
10mysql="mysql -uroot -ptest"
11mysqldump="mysqldump -uroot -ptest"
12[ -d $path ]||mkdir $path -p
13for dbname in `$mysql -e "show databases;" 2>/dev/null|grep -v _schema|sed 1d`
14do
15$mysqldump -B $dbname|gzip >$path/${dbname}_$(date +%F).sql.gz 2>/dev/null
16done
17
xxxxxxxxxx
211mysql数据库分库分表备份
2mysqldump mei t1 t2|gzip >bak.sql.gz
3mysqldump -B mei |gzip >bak.sql.gz:
4mysqldump mei t1
5mysqldump mei t2
6mysqldump mei t3
7
8
9path=/backup
10[ -d $path ]||mkdir $path -p
11for dbname in `mysql -e "show databases;"|grep -v _schema|sed 1d`
12do
13 for tname in `mysql -e "show tables from $dbname;"|sed 1d`
14 do
15 if [ "$dbname" = "mysql" ];then
16 mysqldump --skip-lock-tables $dbname $tname|gzip >$path/${dbname}-${tname}.sql.gz
17 else
18 mysqldump $dbname $tname|gzip >$path/${dbname}-${tname}.sql.gz
19 fi
20done
21
xxxxxxxxxx
1581SSH免交互批量分发脚本(CentOS6)
2
3# mzy 2019-09-22 Add Features
4# another: meizy
5# contact QQ:359462962
6export PATH=/bin:$PATH
7
8# output command help manual
9function output_help(){
10 echo -e "Usage :\n\n--help|-h\tget command help.\n\te.g:batchsent.sh --help\n\ncommand public key distribution:\n\t\e[40;32;1mbatchsent.sh [ip/hostname]\e[0;0;0m\n\nexample:\n\te.g:batchsent.sh 192.168.0.1\n\tor use default batchsent public key:\n\te.g:batchsent.sh\n\nexplanation:\n\t1.hostname needs to be able to be resolved IP address.\n\t2.Run this script need to have root privileges.\n\t3.The current system needs to be able to use yum install sshpass software."
11}
12
13# Check whether the IP address or host name of the obvious error
14function check_ip_format(){
15 ip=$1
16 echo ${ip} |sed -r 's#([0-9]+).#\1#g' |test -n "`sed -n '/^[0-9][0-9]*$/p'`" >/dev/null 2>&1
17 if [ $? -eq 0 ];then
18 count=`echo ${ip}|sed -r 's#([0-9]+).#\1\n#g'|grep -v '^$' | wc -l`
19 if [ ${count} -eq 4 ];then
20 return 0
21 else