shell笔记
~20~shell
shell是一个命令解释器
查看系统的shell
[root@liwx ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
[root@liwx ~]# echo $SHELL
/bin/bash
python运维开发实战课程,课程表是:http://oldboy.blog.51cto.com/2561410/1123127
shell 处理操作系统底层的脚本,简单,易用,高效
python 处理复杂的逻辑程序,
php 前端的页面开发,web的开发
java 后台的开发,更复杂的逻辑程序,安全性更好些
脚本的第一行
#!/bin/bash
#!/bin/sh
[root@liwx scripts]# ls -l `which sh`
lrwxrwxrwx. 1 root root 4 May 15 10:33 /bin/sh -> bash
[root@MySQL ~]# tail -2 /etc/init.d/functions
echo "I am oldboy linux"
}
[root@MySQL ~]# cat test.sh
. /etc/init.d/functions
oldboy
脚本开发的基本规范及习惯
1)脚本第一行指定脚本解释器
2)脚本开头加版本版权等信息
3)脚本中尽量不用中文注释
4)脚本以.sh为扩展名
5)成对的符号要一次性写全,然后退格,流程语句要一次性写完,代码要缩进
老师推荐的shell书
http://www.gnu.org/software/bash/manual/bash.html
man bash
Unix shell范例精解(第4版)-老男孩推荐大家此书
shell-abs-3.9.1_cn_老男孩培训推荐
http://manual.51yip.com/shell/
shell变量
变量类型:
1.环境变量
2.局部变量
环境变量(一般大写)
env|grep -i root
printenv
export
USER=root
MAIL=/var/spool/mail/root
PATH=/application/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
HOME=/root
LOGNAME=root
OLDPWD=/root
[root@liwx scripts]# echo $UID
0
[root@liwx scripts]# echo $USER
root
[root@liwx scripts]# echo $HOME
/root
[root@liwx scripts]# echo $BASH
/bin/bash
[root@liwx scripts]# echo $PS1
[\u@\h \W]\$
全局环境变量地点
/etc/profile.d
/etc/profile
/etc/bashrc
用户环境变量
[root@liwx scripts]# ls -la /home/liwx/
-rw-r--r--. 1 liwx liwx 176 Oct 16 2014 .bash_profile
-rw-r--r--. 1 liwx liwx 124 Oct 16 2014 .bashrc
设置环境变量
export LANG=en
或者
LANG=en
export LANG
环境变量的显示与取消
显示 $HOME(大写)
env
set
unset取消环境变量
unset OLDBOY
[root@mysql-2 ~]# echo $LIEX
[root@mysql-2 ~]# echo $LIWX
22
[root@mysql-2 ~]# unset LIWX
[root@mysql-2 ~]# echo $LIWX
局部变量
变量名=‘value‘
变量名="value"
一般是有字母,数字,下划线组成,以字母开头
oldboy,oldboy123,oldboy_training
source或者.会把脚本里的变量定义到系统
[root@mysql-2 bianliang]# sh test1.sh
123
[root@mysql-2 bianliang]# echo $liwx
[root@mysql-2 bianliang]# source test1.sh
123
[root@mysql-2 bianliang]# echo $liwx
123
单引号,双引号
无引号 简单的,连续的,整体的,路径,字符串,有命令要用反引号,可用双引号替代
‘‘ 所见即所得 不解析变量
"" 解析变量,
`` 一般用于引用命令,执行的时候命令会被执行,相当于$()
1,在脚本中第一普通字符串变量,尽量用双引号
2,单纯数字内容可以不加引号.
3,希望原样输出加单引号,
4,awk,sed单引号和双引号里面的变量,正好与shell相反.
一道实用linux运维问题的9种shell解答方法
http://oldboy.blog.51cto.com/2561410/760192
把命令作为变量
a=`ls`
a=$(ls)
tar zcvf etc_$(date +%F).tar.gz /etc/hosts
ls -lrt
rm -f etc_2015-08-11.tar.gz
tar zcvf etc_`date +%F`.tar.gz /etc/hosts
变量定义小结
普通变量:
a=1 连续的数字
a="/etc/rc.local $USER"
a=‘$USER‘ 原样输出
命令变量
a=`ls` 反引号
a=$()
变量定义小技巧
`` tab键上边的,不是单引号
$ 变量前加$,可以echo,print取变量的值,
{} 边界问题
"" 养成所用字符串变量用""括起来
特殊变量
1)$1...$n 传参变量
用法:启动脚本
$n 获取当前执行的shell脚本的第n个参数值,n=1..9 ,当 n 为0时表示脚本的文件名,如果n大于9,用大括号括起来${10},参数以空格隔开。
2)$0 取脚本的名字,也包含路径
用法:报错时,取脚本的路径和名字
[root@liwx home]# cat /server/scripts/test.sh
dirname $0 #取路径
basename $0 #取脚本名
[root@liwx home]# sh /server/scripts/test.sh
/server/scripts
test.sh
3)$# 取传参的个数
用法:用来判断参数的个数
[ $# -ne 2 ] 如不等于2
进程状态变量
4)$? 获取上一次命令执行情况的返回值
0 成功运行
2 权限拒绝
1-255 失败
在脚本里调用,一般用exit0,脚本返回值给$?
函数里return0返回 返回值给$?
用法
1)判断命令或者脚本是否执行成功
2)通过在脚本里执行exit数字,则脚本返回这个数字给$?
如果是函数用return 数字,返回数字给$?
[root@MySQL 01]# cat t1.sh
#!/bin/sh
[ $# -ne 2 ] && {
echo "$0 ARG1 ARG2"
exit 111 #赋值给当前shell的$?
}
[root@mysql-2 bianliang]# sh test1.sh
test1.sh ARG1 ARG2
[root@mysql-2 bianliang]# echo $?
111
$*和$@
$* 将所有的参数视为单个字符串"$1$2$3"
$@ 接受所有参数 "$1""$2""$3"
$* 和 $@的区别?
$*是获取所有传参的参数,他会把将所有的参数视为单个字符串
$@它把程序里的所有参数,以"$1""$2""$3"来显示,每一个都是独立的个体
$*所有传参的参数当成一个
$@所有参数当成单个的个体
其他:linux下set和eval的使用小案例精彩解答(特殊位置变量用法)
http://oldboy.blog.51cto.com/2561410/1175971
$$ 当前shell执行的进程号,pid
kill -USR2 `cat /tmp/a.pid`
#!/bin/sh
pidpath=/tmp/a.pid
if [ -f "$pidpath" ]
then
kill -USR2 `cat $pidpath` >/dev/null 2>&1
rm -f $pidpath
fi
echo $$ >$pidpath
sleep 300
$! 执行上一次命令的PID
man bash
变量字串的常用操作
1.统计字符串长度的方法
OLDBOY="I am oldboy"
法1
echo ${#OLDBOY}
11
法2
echo $OLDBOY|wc -L
11
法3
expr length "$OLDBOY"
11
面试题,取字符串小于6的单词
for n in I am oldboy linux welcome to our training.
do
if [ ${#n} -lt 6 ]
then
echo $n
fi
done
2.截取一部分内容输出
[root@MySQL 01]# echo $OLDBOY
I am oldboy
[root@MySQL 01]# echo ${OLDBOY:2}
am oldboy
[root@MySQL 01]# echo ${OLDBOY:2:6}
am old
[root@MySQL 01]# echo ${OLDBOY:2:2}
am
[root@MySQL 01]# echo ${OLDBOY:3:2}
m
[root@MySQL 01]# echo ${OLDBOY:3:3}
m o
[root@MySQL 01]# echo ${OLDBOY:3}
m oldboy
[root@MySQL 01]# echo $OLDBOY
I am oldboy
[root@MySQL 01]# echo ${OLDBOY:2}
am oldboy
[root@MySQL 01]# echo ${OLDBOY:2:6}
am old
[root@MySQL 01]# echo ${OLDBOY:2:2}
am
[root@MySQL 01]# echo ${OLDBOY:3:2}
m
[root@MySQL 01]# echo ${OLDBOY:3:3}
m o
[root@MySQL 01]# echo ${OLDBOY:3}
m oldboy
${OLD##abc} 从开头开始删除匹配的最长长度字符串
[root@MySQL 01]# OLDBOY=abcABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY}
abcABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY#a*C}
123ABCabc
[root@MySQL 01]# echo ${OLDBOY#a*c}
ABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY##a*c}
[root@MySQL 01]# echo ${OLDBOY##a*C}
abc
3.变量删除
${%} 从结尾开始删除匹配的最短长度字符串
${##} 从结尾开始删除匹配的最长长度字符串
[root@MySQL 01]# echo ${OLDBOY%a*C}
abcABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY%a*c}
abcABC123ABC
[root@MySQL 01]# echo ${OLDBOY%C*c}
abcABC123AB
[root@MySQL 01]# echo ${OLDBOY%%C*c}
abcAB
[root@MySQL 01]# echo ${OLDBOY%%C*c}
[root@MySQL 01]# OLDBOY="I am oldboy oldboy oldgirl"
[root@MySQL 01]# echo ${OLDBOY/oldboy/etiantian}
I am etiantian oldboy oldgirl
[root@MySQL 01]# echo ${OLDBOY/#I*oldboy/etiantian}
etiantian oldgirl
[root@MySQL 01]# echo ${OLDBOY/%rl/etiantian}
I am oldboy oldboy oldgietiantian
小结:
# 开头删除匹配最短
## 开头删除匹配最长
% 结尾删除匹配最短
$$ 结尾删除配置最长
-防止空值
-防止空值,备胎
[root@MySQL 01]# pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
[root@MySQL 01]# echo $pidfile
/var/run/httpd/httpd.pid
[root@MySQL 01]# PIDFILE=/etc/rc.local
[root@MySQL 01]# pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
[root@MySQL 01]# echo $pidfile
/etc/rc.local
变量的数值计算
变量计算的常用命令
(())、let、expr、bc(可以计算小数) $[],其它都是整数。
1.(())
1.(())用法(常用)
* / % 乘,处,取余
** 幂运算
+=,-= a+=1 相当于 a=a+1
shell的运算实例
[root@liwx home]# ((a=1+2**3-4%3))
[root@liwx home]# echo $a
8
[root@mysql-2 bianliang]# b=$((1+2**3-4%3))
[root@mysql-2 bianliang]# echo $b
8
[root@liwx home]# echo $((1+2**3-4%3))
8
记忆方法:++,--
变量a在前,表达式的值为a,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减。
i++[root@MySQL 01]# myvar=99
[root@MySQL 01]# echo $((myvar+1))
100
[root@MySQL 01]# echo $((myvar-1))
98
[root@MySQL 01]# echo $((myvar-1))
98
[root@MySQL 01]# echo $((100/5))
20
[root@MySQL 01]# echo $((100+5))
105
[root@MySQL 01]# echo $((100*5))
500
[root@MySQL 01]# echo $((100**5))
10000000000
[root@MySQL 01]# echo $((100%5))
0
[root@liwx scripts]# vim test.sh
#!/bin/bash
a=6
b=2
echo "a-b =$(( $a - $b ))"
echo "a+b =$(( $a + $b ))"
echo "a*b =$(( $a * $b ))"
echo "a/b =$(( $a / $b ))"
echo "a**b =$(( $a ** $b ))"
echo "a%b =$(( $a % $b ))"
[root@liwx scripts]# sh test.sh
a-b =4
a+b =8
a*b =12
a/b =3
a**b =36
a%b =0
[root@liwx scripts]# vim test.sh
#!/bin/bash
a=$1
b=$2
echo "a-b =$(( $a - $b ))"
echo "a+b =$(( $a + $b ))"
echo "a*b =$(( $a * $b ))"
echo "a/b =$(( $a / $b ))"
echo "a**b =$(( $a ** $b ))"
echo "a%b =$(( $a % $b ))"
[root@liwx scripts]# sh test.sh 10 5
a-b =5
a+b =15
a*b =50
a/b =2
a**b =100000
a%b =0
网友的例子:
http://chenhao6.blog.51cto.com/6228054/1232070
http://zhangbo.blog.51cto.com/350645/1172900
http://blog.163.com/shaohj_1999@126/blog/static/634068512011388519129/
作业:本周每人完成一个简单的四则运算计算器功能
2.let
[root@MySQL 01]# i=1
[root@MySQL 01]# let i=i+100
[root@MySQL 01]# echo $i
101
提示:let i=i+8等同于((i=i+8)),但后者效率更高
3.expr计算
[root@liwx scripts]# expr 2 + 2
4
[root@liwx scripts]# expr 2 * 2
expr: syntax error
[root@liwx scripts]# expr 2 \* 2
4
[root@liwx scripts]# expr 2 - 2
0
[root@liwx scripts]# expr 2 % 2
0
[root@mysql-2 bianliang]# expr $[2*3]
6
[root@mysql-2 bianliang]# expr $[2+3]
5
[root@mysql-2 bianliang]# expr $[2-3]
-1
expr 运算好两边必须有 "空格"
4.判断扩展名
if expr "$1" : ".*\.pub" &>/dev/null
then
echo "you are using $1"
else
echo "pls use *.pub file"
fi
5.判断变量是否为整数
[root@MySQL 01]# cat judge_int.sh
read -p "Pls input:" a
expr $a + 1 &>/dev/null
[ $? -eq 0 ] && echo int||echo chars
法2
expr match整数判断
[[ `expr match "$a" "[0-9][0-9]*$"` == 0 ]] && {
echo "the first is not a num"
exit 3
}
6.计算字符串长度
[root@MySQL 01]# chars=`seq -s" " 100`
[root@MySQL 01]# echo $chars
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
法1(最常用,效率最高)
[root@MySQL 01]# echo ${#chars}
291
法2
[root@MySQL 01]# echo $(expr length "$chars")
291
法3
[root@MySQL 01]# echo ${chars}|wc -L
291
[root@MySQL 01]# time for i in $(seq 11111);do count=${#chars};done;
real 0m0.512s
user 0m0.503s
sys 0m0.001s
[root@MySQL 01]# time for i in $(seq 11111);do count=`echo ${chars}|wc -L`;done;
real 0m21.410s
user 0m0.869s
sys 0m2.123s
[root@MySQL 01]# time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done;
real 0m5.702s
user 0m0.391s
sys 0m1.230s
[root@MySQL 01]# grep "host" /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 MySQL
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
7.bc计算器
bc计算器
[root@liwx scripts]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty‘.
5.6-5.5
.1
bc是unix下的计算器,可以算小数
[root@liwx scripts]# i=2
[root@liwx scripts]# i=`echo $i+1|bc`
[root@liwx scripts]# echo $i
3
[root@liwx scripts]# echo "5.6-5.4"|bc
.2
#保留几位
[root@MySQL 01]# echo "scale=3;5.23 / 3.13"|bc
1.670
7.awk方法
echo "$NEWCONN1 $NEWCONN2" |awk ‘{print ($2-$1)/5}‘
awk也可以计算小数……
[root@liwx scripts]# echo "5.6 5.5"|awk ‘{print ($1-$2)}‘
0.1
[root@liwx scripts]# echo "5.6 5.5"|awk ‘{print ($1-$2)/5}‘
0.02
范例:通过一条命令计算输出1+2+3..+10的表达式,并计算出结果,使用bc计算?
输出内容如:1+2+3+4+5+6+7+8+9+10=55
法1
echo "`seq -s ‘+‘ 10`="$((`seq -s "+" 10`))
1+2+3+4+5+6+7+8+9+10=55
法2
echo `seq -s ‘+‘ 10`=`seq -s "+" 10|bc`
1+2+3+4+5+6+7+8+9+10=55
法3
echo `seq -s ‘+‘ 10`=`seq -s " + " 10|xargs expr`
1+2+3+4+5+6+7+8+9+10=55
法4
echo {1..9}"+" 10 =`echo {1..9}"+" 10|bc`|sed ‘s# ##g‘
1+2+3+4+5+6+7+8+9+10=55
8.$[]
[root@MySQL 01]# i=1
[root@MySQL 01]# i=$[ i + 1 ]
[root@MySQL 01]# echo $i
2
read变量赋值
语法
read 参数 变量名
-p 设置提示信息
-t 设置输入等待的时间
[root@mysql-2 scripts]# read -t 5 -p "pls input:"a #a前面要有空格
pls input:1
[root@mysql-2 scripts]# echo $a
1
[root@mysql-2 scripts]# read -t 5 -p "pls input:" a b c
pls input:1 2 3
[root@mysql-2 scripts]# echo $a $b $c
1 2 3
用shell脚本实现杨辉三角的3个实例(第一种为重点h)
http://oldboy.blog.51cto.com/2561410/756234
19:38 2015/8/11
课后作业:
1、shell脚本基础,shell介绍,重要性
2、写脚本规范,脚本的建立和执行。
3、shell,php,perl,python特点及区别
4、全局变量、普通变量的定义规范,定义方法
5、特殊变量,位置变量,进程状态变量
6、变量的字串知识
7、变量的数值计算:
(()),let,expr,bc(小数awk),$[]
预习:
1、条件测试
2、if语句
3、case语句
4、while循环
条件测试与比较
条件测试语法格式
语法格式1: test <测试表达式>
语法格式2: [ <测试表达式> ]
语法格式3: [[ <测试表达式> ]]
man test
1.test
test判断文件或者目录
test -f /etc/hosts && echo 1||echo 0
1
test -f /etc && echo 1||echo 0
0
test -d /etc && echo 1||echo 0
1
取反
test ! -f /etc && echo 1||echo 0
1
判断字符串是否为0
test -z "oldboy"&&echo 1||echo 0
0
test -z ""&&echo 1||echo 0
1
2.[ ]
[ -f ] -f两端必须都有空格
[ -z "oldboy" ] && echo 1||echo 0
0
[ -z "" ] && echo 1||echo 0
1
[ -f /etc/hosts ] && echo 1||echo 0
1
[ -f /etc ] && echo 1||echo 0
0
3.[[]]
判断文件或者目录
[root@MySQL ~]# [[ -f "/etc/hosts" ]]&&echo 1||echo 0
1
[root@MySQL ~]# [[ -e "/etc/hosts" ]]&&echo 1||echo 0
1
[root@MySQL ~]# [[ ! -e "/etc/hosts" ]]&&echo 1||echo 0
0
4.[]和[[]]的区别
[[ ]] 逻辑符号用&& 或者 ||
[ ] 逻辑符号用-a 或者 -o
[root@MySQL ~]# [[ -e "/etc/hosts" && -f /etc/hosts ]]&&echo 1||echo 0
1
[root@MySQL ~]# [[ -e "/etc/hosts" || -f /etc/hosts ]]&&echo 1||echo 0
1
[root@MySQL ~]# [ -e "/etc/hosts" || -f /etc/hosts ]&&echo 1||echo 0
-bash: [: missing `]‘
-bash: -f: command not found
0
[root@MySQL ~]# [ -e "/etc/hosts" -o -f /etc/hosts ]&&echo 1||echo 0
1
[root@MySQL ~]# [ -e "/etc/hosts" -a -f /etc/hosts ]&&echo 1||echo 0
1
文件测试表达式
-f 文件(普通文件)
[root@liwx ~]# [ -f oldboy ]&& echo 1
1
[root@liwx ~]# [ -f oldboy ]||1
-d 目录
[root@liwx ~]# [ -f oldboy1 ]||echo 1
1
[root@liwx ~]# [ -d oldboy1 ]||echo 1
[root@liwx ~]# [ -f oldboy1 ]&&echo 1||echo 0
0
-e 文件(只要是文件就可以)
[root@liwx ~]# [ -e oldboy1 ]&&echo 1||echo 0
1
-r 可读
-w 可写
-x 可执行
测试变量
文件
[root@liwx ~]# file1=/etc/services ;file2=/etc/rc.local
[root@liwx ~]# echo $file1
/etc/services
[root@liwx ~]# echo $file2
/etc/rc.local
[root@liwx ~]# [ -f "$file2" ] &&echo 1||echo 0
1
[root@liwx ~]# [ -f "$file1" ] &&echo 1||echo 0
1
[root@liwx ~]# [ -d "$file1" ] &&echo 1||echo 0
0
[root@liwx ~]# [ -e "$file1" ] &&echo 1||echo 0
1
目录
[root@liwx ~]# dir1=/etc
[root@liwx ~]# [ -d "$dir1" ] &&echo 1||echo 0
1
[root@liwx ~]# [ -e "$dir1" ] &&echo 1||echo 0
1
[root@liwx ~]# [ -w "$dir1" ] &&echo 1||echo 0
1
[root@liwx ~]# [ -x "$dir1" ] &&echo 1||echo 0
1
测试
#!/bin/sh
[ -f /tmp/oldboy.log ]||exit 5 #不存在就退出
cat /tmp/oldboy.log #存在就查看
多个条件
[root@MySQL 02]# [ -f "$file1" -a -f "$file2" ] &&echo 1||echo 0
1
[root@MySQL 02]# [ -f "$file1" -o -f "$file2" ] &&echo 1||echo 0
1
[root@MySQL 02]# [ -f "$file1" -a -f "$file2" ] &&echo 1||echo 0
1
[root@MySQL 02]# [ ! -f "$file1" -a -f "$file2" ] &&echo 1||echo 0
0
多个命令
[root@MySQL 02]# sh f.sh
[root@MySQL 02]# echo 123 >/tmp/oldboy.log
[root@MySQL 02]# sh f.sh
123
1
[root@MySQL 02]# cat f.sh
#!/bin/sh
[ -f /tmp/oldboy.log ]&&{
cat /tmp/oldboy.log
echo 1
exit
}
等于if语句
if [ -f /tmp/oldboy.log ];then
cat /tmp/oldboy.log
echo 1
exit
fi
[ 3 -ne 3 ] ||{ echo ‘I am oldboy‘;echo "I am coming";exit 1; }
字符串测试表达式
字符串测试操作符的作用,比较两个字符串是否相同,字符串长度是否为0,字符串是否为NULL
1.判断字符串是否为空
[root@mysql-2 scripts]# [ -n "abc" ]&&echo 1||echo 2
1
[root@mysql-2 scripts]# [ -n "" ]&&echo 1||echo 2
2
[root@mysql-2 scripts]# [ -z "abc" ]&&echo 1||echo 2
2
[root@mysql-2 scripts]# [ -z "" ]&&echo 1||echo 2
1
[root@MySQL ~]# sed -n ‘30,31p‘ /etc/init.d/network
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 6
[root@MySQL ~]# [ "abc" != "abc " ]&&echo 1||echo 0
1
[root@MySQL ~]# [ "abc" != "abc" ]&&echo 1||echo 0
0
[root@MySQL ~]# test="abc"
[root@MySQL ~]# [ "$test" != "abc" ]&&echo 1||echo 0
0
[root@MySQL ~]# test1=abd
[root@MySQL ~]# [ "$test" = "$test1" ]&&echo 1||echo 0
0
[root@MySQL ~]# [ "${#test}" = "${#test1}" ]&&echo 1||echo 0
1
多个字符串
整数二元比较操作符
-eq ==或= equal
-ne != not equal
-gt > greater than
-ge <= greater equal
-lt < less than
-le <= less equal
不推荐用=><符号,符号需要转译
[root@liwx ~]# [ 2 > 1 ]&&echo 1||echo 0
1
[root@liwx ~]# [ 2 > 3 ]&&echo 1||echo 0
1
[root@liwx ~]# [ 2 \> 3 ]&&echo 1||echo 0
0
用-gt
[root@liwx ~]# [ 2 -gt 3 ]&&echo 1||echo 0
0
[root@liwx ~]# [ 2 -lt 3 ]&&echo 1||echo 0
1
[root@liwx ~]# [ 2 -eq 3 ]&&echo 1||echo 0
0
[[]]双中括号 可以用<>=
[root@liwx ~]# [[ 2 > 3 ]]&&echo 1||echo 0
0
整数比较,推荐的方法
[ $num1 -eq $num2 ] #注意空格,和比较符号
(($num1>$num2)) #无需空格,常规数学比较符号
逻辑操作字符
[] [[]]
-a && and
-o || 或
! ! 非
[root@MySQL ~]# sed -n ‘87,90p‘ /etc/init.d/nfs
[ "$NFSD_MODULE" != "noload" -a -x /sbin/modprobe ] && {
/sbin/modprobe nfsd
[ -n "$RDMA_PORT" ] && /sbin/modprobe svcrdma
}
利用条件表达式完成
比较两个整数的大小
[root@MySQL scripts]# cat cmp2.sh
#!/bin/sh
#no.1 judge arg nums.
[ $# -ne 2 ]&&{
echo "USAGE:"$0" num1 num2"
exit 1
}
#no.2 judge if int.
expr $1 + 1 &>/dev/null
RETVAL1=$?
expr $2 + 1 &>/dev/null
RETVAL2=$?
[ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ]&&{
echo "pls input two nums."
exit 2
}
[ $RETVAL1 -ne 0 ]&&{
echo "The first num is not int,pls input again."
exit 2
}
[ $RETVAL2 -ne 0 ]&&{
echo "The second num is not int,pls input again."
exit 3
}
#no.3 compare two int.
[ $1 -lt $2 ]&&{
echo "$1<$2"
exit 0
}
[ $1 -eq $2 ]&&{
echo "$1=$2"
exit 0
}
[ $1 -gt $2 ]&&{
echo "$1>$2"
exit 0
}
变量的三种输入方式:
1.定义 a=1
2.传参方式 $1
3.read交互式读入
[root@liwx scripts]# cat ad.sh
#!/bin/sh
read -t 5 -p "Pls input a character:" a
echo "your input is:$a"
多级菜单脚本
综合实例:打印选择菜单,一键安装Web服务:
[root@oldboy scripts]# sh menu.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
要求:
1、当用户输入1时,输出"start installing lamp."然后执行/server/scripts/lamp.sh,脚本内容输出"lamp is installed"后退出脚本;
2、当用户输入2时,输出"start installing lnmp." 然后执行/server/scripts/lnmp.sh输出"lnmp is installed"后退出脚本;
3、当输入3时,退出当前菜单及脚本;
4、当输入任何其它字符,给出提示"Input error"后退出脚本。
5、要对执行的脚本进行相关条件判断,例如:脚本是否存在,是否可执行等
[root@MySQL scripts]# cat menu1.sh
#!/bin/sh
#no.1 menu
cat <<EOF
1.[install lamp]
2.[install lnmp]
3.[exit]
EOF
#no.2
read -t 20 -p " pls input the num you want:" num
[ "$num" != "1" -a "$num" != "2" -a "$num" != "3" ]&&{
echo "Input error"
exit
}
#no.3
[ $num -eq 1 ]&&{
echo "install lamp"
[ -f /server/scripts/lamp.sh ]&&\
/bin/sh /server/scripts/lamp.sh
exit
}
[ $num -eq 2 ]&&{
echo "install lnmp"
[ -f /server/scripts/lnmp.sh ]&&\
/bin/sh /server/scripts/lnmp.sh
exit
}
[ $num -eq 3 ]&&{
echo "bye!"
exit
}
if条件句
单分支结构
或者
if [条件];then
指令
fi
案例1
[root@liwx scripts]# cat bc.sh
#!/bin/sh
if [ -f /etc/hosts ];then
echo 1
fi
案例2
范例2:开发脚本判断系统剩余内存大小,如果低于100M就邮件报警,并且加入系统定时任务每3分钟执行一次检查。
配置mail
echo -e "set from=oldboy@163.com smtp=smtp.163.com\nset smtp-auth-user=oldboy smtp-auth-password=oldboy123 smtp-auth=login" >>/etc/mail.rc
#!/bin/bash
mem=`free -m|awk -F‘[ :]+‘ ‘NR==3 {print $4}‘`
if [ $mem -le 100 ];then
echo "内存不足可用内存为:${mem}M"|mail -s "内存警告" shmilyjinian@163.com
fi
[root@liwx scripts]# cat free.sh
#!/bin/sh
MEM=`free -m|awk ‘NR==3 {print $4}‘`
if [ $MEM -lt 2000 ];then
echo "The memory_$(date +%F-%R)_warning:: $MEM"
exit 1
fi
双分支结构
语法:
if [ 条件 ]
then
指令
else
指令
fi
或者
if [条件];then
指令
fi
范例1:用if双分支实现对nginx服务是否正常判断,使用进程数的方式判断,如果进程没起,把进程启动。
[root@lnmp ~]# cat check_web.sh
#!/bin/sh
if [ `ps -ef|grep "nginx"|egrep -v "php-fpm|grep"|wc -l` -ge 2 ]
then
echo "Nginx is running."
else
echo "Nginx is stopped."
/application/nginx/sbin/nginx
fi
[root@lnmp ~]# ps -C nginx
PID TTY TIME CMD
10437 ? 00:00:00 nginx
10438 ? 00:00:00 nginx
10439 ? 00:00:00 nginx
10440 ? 00:00:00 nginx
10441 ? 00:00:00 nginx
10442 ? 00:00:00 nginx
10443 ? 00:00:00 nginx
10444 ? 00:00:00 nginx
10445 ? 00:00:00 nginx
10446 ? 00:00:00 nginx
10447 ? 00:00:00 nginx
[root@lnmp ~]# ps -C nginx --no-header
多分支结构
语法
if 条件1
then
指令1
then
指令2
else
指令3
fi
范例3:使用if多分支语句、read及脚本传参方式如何实现2个整数比较大小?
[root@liwx scripts]# vim arg2.sh
#!/bin/sh
#no.1 judge arg nums.
[ $# -ne 2 ]&&{
echo "USAGE:"$0" num1 num2"
exit 1
}
#no.2 judge if int.
expr $1 + 1 &>/dev/null
RETVAL1=$?
expr $2 + 1 &>/dev/null
RETVAL2=$?
if [ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ];then
echo "pls input two nums."
exit 1
fi
if [ $RETVAL1 -ne 0 ];then
echo "The first num is not int,pls input again."
exit 2
fi
if [ $RETVAL2 -ne 0 ];then
echo "The second num is not int,pls input again."
exit 3
fi
if [ $1 -lt $2 ]
then
echo "$1<$2"
exit 0
elif [ $1 -eq $2 ]
then
echo "$1=$2"
exit 0
else
echo "$1>$2"
fi
[root@MySQL 02]# cat if-judge2-by-arg.sh
#!/bin/bash
a=$1
b=$2
#no.1 judge arg nums.
if [ $# -ne 2 ];then
echo "USAGE:$0 arg1 arg2"
exit 2
fi
#no.2 judge if int
expr $a + 1 &>/dev/null
RETVAL1=$?
expr $b + 1 &>/dev/null
RETVAL2=$?
if [ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ];then
echo "please input two int again"
exit 3
fi
if [ $RETVAL1 -ne 0 ];then
echo "The first num is not int,please input again"
exit 4
fi
if [ $RETVAL2 -ne 0 ];then
echo "The second num is not int,please input again"
exit 5
fi
#no.3 compart two num.
if [ $a -lt $b ];then
echo "$a<$b"
exit
elif [ $a -eq $b ];then
echo "$a=$b"
exit
else
echo "$a>$b"
fi
[root@MySQL 02]# cat if-judge2-by-read.sh
#!/bin/bash
read -p "pls input two num:" a b
#no.1 judge read.
[ -z "$a" ]||[ -z "$b" ] && {
echo "pls input two num agagin"
exit 1
}
#no.2 judge if int
expr $a + 1 &>/dev/null
RETVAL1=$?
expr $b + 1 &>/dev/null
RETVAL2=$?
if [ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ];then
echo "please input two int again"
exit 3
fi
if [ $RETVAL1 -ne 0 ];then
echo "The first num is not int,please input again"
exit 4
fi
if [ $RETVAL2 -ne 0 ];then
echo "The second num is not int,please input again"
exit 5
fi
#no.3 compart two num.
if [ $a -lt $b ];then
echo "$a<$b"
exit
elif [ $a -eq $b ];then
echo "$a=$b"
exit
else
echo "$a>$b"
fi
范例4:实现通过传参的方式往/etc/user.conf里添加用户,具体要求如下:
1)命令用法:
USAGE: sh adduser {-add|-del|-search} username
2)传参要求:
如果参数为-add时,表示添加后面接的用户名,
如果参数为-del时,表示删除后面接的用户名,
如果参数为-search时,表示查找后面接的用户名,
3)如果有同名的用户则不能添加,没有对应用户则无需删除,查找到用户以及没有用户时给出明确提示。
4)/etc/user.conf不能被所有外部用户直接删除及修改
北京-郭雨明 20:12:05
#!/bin/bash
username=$2
file=/etc/user.conf
if [ $# -ne 2 ];then
echo "USAGE:$0 {-add|-del|-search} username"
exit 2
fi
case "$1" in
-add|--add)
if [ `grep "\<$username\>" /etc/user.conf |wc -l` -ne 0 ];then
echo "user exist"
else
echo $username >>$file
fi
;;
-del|--del)
if [ `grep "\<$username\>" /etc/user.conf |wc -l` -eq 0 ];then
echo "user not exist"
else
sed -i "/\<$username\>/d" $file
fi
;;
-search|--search)
if [ `sed -n "/\<$username\>/p" $file |wc -l` -eq 0 ];then
echo "no such user"
else
echo $username
fi
;;
*)
echo "error arg"
exit
esac
企业案例:写网络服务rsync的系统启动脚本
范例3 :利用if语句开发类似系统启动rsync服务的脚本
(可参考系统的rpcbind/nfs/crond脚本)!
例如:/etc/init.d/rsyncd {start|stop|restart}
测试用例:
[root@oldboy 04]# touch /etc/rsyncd.conf
[root@oldboy 04]# rsync --daemon
[root@oldboy 04]# lsof -i :873
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsync 14085 root 4u IPv4 555582 0t0 TCP *:873 (LISTEN)
rsync 14085 root 5u IPv6 555583 0t0 TCP *:873 (LISTEN)
#!/bin/sh
[ -f /etc/rsyncd.conf ] || {
echo
}exit
then
echo "USAGE: /etc/init.d/$0 {start|stop|restart}"
exit 1
fi
[root@mysql ~]# cat rsync.sh
#!/bin/sh
[ -f /etc/rsyncd.conf ]&&touch /etc/rsyncd.conf&&\
if [ $# -ne 1 ]
then
echo "USAGE: /etc/init.d/$0 {start|stop|restart}"
exit 1
fi
if [ "$1" == "start" ]
then
rsync --daemon
echo "rsync is running"
exit
fi
if [ "$1" == "stop" ]
then
pkill rsync
echo "rsync is stopping"
exit
fi
if [ "$1" == "restart" ]
then
pkill rsync &&\
rsync --daemon
echo "rsync is restart"
exit
fi
范例4:开发生产mysql多实例启动的脚本(以前的课程内容)
(1)mysql多实例的启动:
[root@oldboy 3306]# /data/3306/mysql start
Starting MySQL...
[root@oldboy 3306]# /bin/sh /application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 > /dev/null &
[1] 31898
[root@oldboy 3306]# netstat -lnt|grep 330 tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
(2)mysql多实例的停止:
[root@oldboy 3306]# /data/3306/mysql stop
Stoping MySQL...
mysqladmin -u root -poldboy -S /data/3306/mysql.sock shutdown
利用if语句开发mysql多实例启动脚本。
武汉-谢迪六组组长(397731124) 9:51:13
[root@mysql ~]# cat mysql.sh
#!/bin/sh
if [ $# -ne 1 ]
then
echo "/data/3306/$0 [start|stop]"
exit
fi
if [ "$1" == "start" ]
then
/bin/sh /application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 > /dev/null &
echo "Starting MySQL...."
exit
fi
if [ "$1" == "stop" ]
then
mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown
echo "Stoping MySQL..."
exit
fi
判断字符串是否为整数
法1
expr $a + $b +1 &>/dev/null
法2
[ -n "`echo 123`"|sed ‘s###g‘ ]
[root@MySQL 3306]# [ -n "`echo "123"|sed ‘s/[0-9]//g‘`" ] && echo char||echo int
int
[root@MySQL 3306]# [ -n "`echo "oldboy123"|sed ‘s/[0-9]//g‘`" ] && echo char||echo int
char
法3
法4
[root@MySQL 3306]# [ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo "it is num"||echo "fei num"
法5
[root@MySQL 3306]# [[ 123 =~ ^[0-9]+$ ]] &&echo int ||echo char
int
[root@MySQL 3306]# [[ oldboy123 =~ ^[0-9]+$ ]] &&echo int ||echo char
char
监控DB服务是否正常,不低于5种思路
方法:web和db共同方法
1、端口
本地:netstat,ss,lsof
远程:telnet,nmap,nc
2、 进程(本地)
====================================
3、wget/curl(http方式,判断根据返回值或者返回内容)。
4、header(http),(http方式,根据状态码判断)
5、数据库特有,通过mysql客户端连接连接,根据返回值或者返回内容。
查看远端的端口是否通畅3个简单实用案例!
http://oldboy.blog.51cto.com/2561410/942530
2、本地进程数
3、header(http code) curl -I web地址返回200就OK。
掌握技术思想比解决问题本身更重要
http://oldboy.blog.51cto.com/2561410/1196298
4、URL(wget,curl)web地址,模拟用户的方式。
5、php,java写一个程序,模拟用户的方式监控(让开发提供)。
http://oldboy.blog.51cto.com/2561410/942530
#注意脚本名不要写成mysql.sh
grep过滤mysql的时候进程会多
4、通过php/java程序url方式监控MySQL(老男孩老师推荐)
最接近模拟用户访问,效果最好。报警的最佳方式不是服务是否开启了,而是网站的用户是否还访问正常。
参考/etc/init.d/rpcbind
1.端口
本地:netstat,ss,lsof
远程;telnet,nmap,nc
大全讲解:
[root@shell 03]# cat check_db.sh
#!/bin/sh
if [ "`netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘`" = "3306" ]
#cuo-if [ `netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘` -eq 3306 ]
#if [ `ps -ef|grep mysql|grep -v grep|wc -l` -gt 0 ]
#if [ `nc -w 2 10.0.0.7 3306 &>/dev/null&&echo ok|grep ok|wc -l` -gt 0 ]
#if [ `nmap 10.0.0.7 -p 3306 2>/dev/null|grep open|wc -l` -gt 0 ]
#if [ `netstat -lntup|grep mysqld|wc -l` -gt 0 ]
#if [ `lsof -i tcp:3306|wc -l` -gt 0 ]
then
echo "MySQL is Running."
else
echo "MySQL is Stopped."
/data/3306/mysql start
fi
本地,端口,进程
[root@MySQL scripts]# cat check_db01.sh
#!/bin/sh
port=`ps -ef|grep mysql|grep -v grep|wc -l`
#port=`lsof -i:3307|grep mysql|wc -l`
#port=`ss -lntup|grep mysql|wc -l`
#port=`netstat -lntup|grep mysql|wc -l`
if [ $port -ne 2 ];then
echo "MySQL is not running"
else
echo "MySQL is running"
fi
远程
监控nginx
#!/bin/sh
#prot=`ss -lntup|grep nginx|wc -l`
prot=`lsof -i:80|grep nginx|wc -l`
prot1=`nmap 10.0.0.5 -p 3307|grep open|wc -l`
#if [ $prot -ne 1 ];then
if [ $prot -ne 2 ];then
echo "nginx is not runnint"
else
echo "nginx is runnint"
fi
wget
[root@MySQL scripts]# cat check_web01.sh
port=`wget -T 10 --spider -t 2 http://10.0.0.5 &>/dev/null`
if [ $? -ne 0 ];then
#if [ $port -ne 1 ];then
echo "httpd is not running"
else
echo "httpd is running"
fi
curl
[root@MySQL scripts]# curl -I -s -w "%{http_code}\n" 10.0.0.5 -o /dev/null
200
[root@MySQL scripts]# cat check_web01.sh
port=`curl -s -I 10.0.0.5|head -1|grep "\b200\b"|wc -l`
#port=`curl --connect-timeout 5 http://10.0.0.5 &>/dev/null`
#port=`wget -T 10 --spider -t 2 http://10.0.0.5 &>/dev/null`
#if [ $port -ne 1 ];then
#if [ $port -ne 1 ];then
if [ "`curl -I -s -w "%{http_code}\n" 10.0.0.5 -o /dev/null`" != "200" ]
then
echo "httpd is not running"
else
echo "httpd is running"
fi
使用grep实现精确过滤的五种方法
http://oldboy.blog.51cto.com/2561410/1685520
[root@MySQL scripts]# cat oldboy.log
200
0200
2000
[root@MySQL scripts]# grep "\b200\b" oldboy.log
200
[root@MySQL scripts]# grep -w "200" oldboy.log
200
[root@MySQL scripts]# grep -x "200" oldboy.log
200
[root@MySQL scripts]# grep "^200$" oldboy.log
200
小结
1.条件表达式
文件,字符串,整数
2.if语句
取值判断
3,函数
函数
shell函数
1.使用函数的优势
函数的作用,把程序里多次调用相同的代码部分定义成一份
1.把相同程序段定义成函数,可以减少整个程序的代码量
2.增加程序的可读,易读性.
3.可以实现程序功能模块化,不同的程序使用函数模块化.
强调:对于shell来说,linux系统的2000多个命令都可以说是shell函数
语法
函数名(){
指令..
return
}
示例
[root@liwx 1]# vim hanshu.sh
liwx(){
echo "i am liwenxue!!"
}
xiaoming(){
echo "i am guoyuming"
}
liwx
xiaoming
[root@liwx 1]# sh hanshu.sh
i am liwenxue!!
i am guoyuming
2.函数的传参
函数名 参数1 参数2
[root@liwx 1]# vim hanshu.sh
who(){
echo "i am $1"
}
who oldboy
[root@liwx 1]# sh hanshu.sh
i am oldboy
[root@liwx 1]# vim hanshu1.sh
who(){
echo "i am $1"
}
who $1
[root@liwx 1]# sh hanshu.sh liwx
i am liwx
3.检查网站是否正常
范例4:函数传参转成脚本命令行传参,对任意指定URL判断是否异常
法1
[root@MySQL scripts]# cat check_weburl.sh
#!/bin/sh
usage(){
echo "USAGE:$0 arg"
exit 1
}
check_web(){
curl -s $1 &>/dev/null
if [ $? -eq 0 ]
then
echo "$1 web is ok"
else
echo "$1 web is no"
fi
}
main(){
if [ $# -ne 1 ]
then
usage
fi
check_web $1
}
main $*
法2
[root@MySQL scripts]# cat func02.sh
#!/bin/sh
check_url(){
wget -T 10 --spider -t 2 $1 &>/dev/null
if [ $? -eq 0 ]
then
echo "$1 is ok."
else
echo "$1 is no."
fi
}
check_url $1
法3
#!/bin/sh
num=`curl -I -s -w "%{http_code}" $1 -o /dev/null`
url(){
if [ "$num" != "200" ];then
echo "the $1 is worng"
else
echo "the $1 is right"
fi
}
url $1
case语句
case就是一个多分支的if语句
语法
case "字符串变量" in
值1) 指令1...
;;
值2) 指令2...
;;
*) 指令...
esac
1.判断数字
如果用户输入1或2或3,则输出对应输入的数字,如果是其他
内容,返回不正确,退出。
老师的方法
[root@MySQL scripts]# cat case01.sh
read -p "Please input a number:" ans
case "$ans" in
1)
echo "the num you input is 1"
;;
2)
echo "the num you input is 2"
;;
[3-9])
echo "the num you input is $ans"
;;
*)
echo "the num you input must be less 9."
exit;
esac
法2
[root@MySQL scripts]# cat if-re-case.sh
#!/bin/sh
read -p "please input a number:" ans
if [ $ans -eq 1 ];then
echo "the num you input is 1"
elif [ $ans -eq 2 ];then
echo "the num you input is 2"
elif [ $ans -ge 3 -a $ans -le 9 ];then #<==此处也可以用正则,双中括号。
echo "the num you input is $ans"
else
echo "the num you input must be less 9."
exit
fi
[root@liwx 1]# vim case1.sh
case "$1" in
1)
echo print $1
;;
2)
echo print $1
;;
3)
echo print $1
;;
*)
echo print error
esac
2.打印水果菜单
1.apple
2.pear
3.banana
4.cherry
当用户选择水果的时候,打印告诉它选择的水果是什么,并给水果单词加上一种颜色。
要求用case语句实现。
#!/bin/sh
RED_COLOR=‘\E[1;31m‘
GREEN_COLOR=‘\E[1;32m‘
YELLOW_COLOR=‘\E[1;33m‘
BLUE_COLOR=‘\E[1;34m‘
RES=‘\E[0m‘
echo -e "$RED_COLOR oldboy $RES"
echo -e "$YELLOW_COLOR gongjie $RES"
[root@liwx 1]# vim color.sh
#!/bin/sh
RED_COLOR=‘\E[1;31m‘
GREEN_COLOR=‘\E[1;32m‘
YELLOW_COLOR=‘\E[1;33m‘
BLUE_COLOR=‘\E[1;34m‘
RES=‘\E[0m‘
#echo -e "$RED_COLOR oldboy $RES"
#echo -e "$YELLOW_COLOR gongjie $RES"
cat <<EOF
1.apple
2.pear
3.banana
4.cherry
q.quit
EOF
while true
do
read -p "please in put [1-4]:" a
case "$a" in
1)
echo -e "$GREEN_COLOR apple $RES"
;;
2)
echo -e "$YELLOW_COLOR pear $RES"
;;
3)
echo -e "$YELLOW_COLOR banana $RES"
;;
4)
echo -e "$RED_COLOR cherry $RES"
;;
q)
exit
;;
*)
echo "print [1-4]"
esac
done
老师的方法
[root@MySQL scripts]# cat case04.sh
#!/bin/sh
add(){
RED_COLOR=‘\E[1;31m‘
GREEN_COLOR=‘\E[1;32m‘
YELLOW_COLOR=‘\E[1;33m‘
BLUE_COLOR=‘\E[1;34m‘
FLASH_COLOR=‘\33[5m‘
RES=‘\E[0m‘
case "$1" in
red|RED)
echo -e "$RED_COLOR $2 $RES"
;;
green|GREEN)
echo -e "$GREEN_COLOR $2 $RES"
;;
yellow|YELLOW)
echo -e "$YELLOW_COLOR $2 $RES"
;;
blue|BLUE)
echo -e "$BLUE_COLOR $2 $RES"
;;
*)
echo "plu use:{red|green|yellow|blue} {chars}"
exit
esac
}
menu(){
cat <<END
=================
1.apple
2.pear
3.banana
4.cherry
5.exit
==================
END
}
fruit(){
read -p "pls input the fruit your like:" fruit
case "$fruit" in
1)
add red apple
;;
2)
add green pear
;;
3)
add yellow banana
;;
4)
add blue cherry
;;
5)
exit
;;
*)
echo "pls select right num:{1|2|3|4}"
exit
esac
}
main(){
while true
do
menu
fruit
done
}
main
3.配置Nginx的启动脚本
已知nginx管理命令为:
启动:
/application/nginx/sbin/nginx
停止:
/application/nginx/sbin/nginx -s stop
重新加载:
/application/nginx/sbin/nginx -s reload
请用case脚本模拟nginx服务启动关闭:
/etc/init.d/nginx {start|stop|restart|reload}
并实现可通过chkconfig管理。
[root@lnmp init.d]# cat nginx
#!/bin/sh
# chkconfig: 2345 54 65
# description: Stop/Start nginx scripts
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
nginx="/application/nginx/sbin/nginx"
prog="nginx"
RETVAL=0
start(){
if [ ! -f /var/lock/subsys/$prog ];then
$nginx && RETVAL=$?
else
echo "Nginx is running."
exit
fi
if [ $RETVAL -eq 0 ];then
touch /var/lock/subsys/$prog
action "Starting nginx" /bin/true
else
action "Starting nginx" /bin/false
fi
return $RETVAL
}
stop(){
if [ -f /var/lock/subsys/$prog ];then
$nginx -s stop && RETVAL=$?
else
echo "Nginx is stopped."
exit
fi
if [ $RETVAL -eq 0 ];then
rm -f /var/lock/subsys/$prog
action "Stopping nginx" /bin/true
else
action "Stopping nginx" /bin/false
fi
return $RETVAL
}
reload(){
if [ -f /var/lock/subsys/$prog ];then
$nginx -s reload && RETVAL=$?
else
echo "Nginx is stopped."
exit
fi
if [ $RETVAL -eq 0 ];then
action "Reloading nginx" /bin/true
else
action "Reloading nginx" /bin/false
fi
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
reload)
reload
;;
*)
echo "USAGE:$0 {start|stop|restart|reload}"
esac
exit $RETVAL
企业案例:开发mysql多实例启动脚本:
已知mysql多实例启动命令为:
mysqld_safe --defaults-file=/data/3306/my.cnf &
停止命令为:
mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown
请完成mysql单实例或多实例启动启动脚本的编写
要求:用函数、case语句等实现。(15分钟)
系统标杆脚本
/etc/init.d/functions
http://www.cnblogs.com/image-eye/archive/2011/10/26/2220405.html
/etc/rc.d/rc.sysinit
/etc/init.d/nfs
/etc/init.d/rpcbind
/etc/init.d/httpd
while条件句
语法
while 条件
do
指令....
done
一直循环,死循环
while true
do
uptime
sleep 2
done
usleep 1000000(微秒)=sleep 1
while读文件的方式
拓展:while按行读文件的方式:
方式1:
exec <FILE
sum=0
while read line
do
cmd
done
方式2:
cat ${FILE_PATH} | while read line
do
cmd
done
方式3:
while read line
do
cmd
done<FILE
例子
[root@MySQL scripts]# cat sum-while.sh
sum=0
while read line
do
i=`echo $line|awk ‘{print $10}‘`
expr $i + 1 &>/dev/null
[ $? -ne 0 ] && continue #continue退出当次循环
((sum+=value))
done<access_2010-12-8.log
echo $sum
法2
while循环小结
-
while循环的特长,执行守护进程,希望循环不退出持续执行的情况,用于频率小于1分钟循环处理,其他的while循环几乎都可以
-
case语句可以用if语句替换一般在系统启动脚本传入少量固定规则字符串,用case语句,其他普通判断多用if
-
一句话,fi,for语句最常用,其次while(守护进程),case(服务启动脚本)
各个语句使用场景
条件表达式 简短的判断(文件是否存在,字符串是否为空等)
if 取值判断,不同值数量较少的情况.
while 守护进程无限循环(sleep)
case 服务启动脚本,菜单
for 正常的循环处理,最常用
函数 逻辑清晰,减少重复语句.
防止脚本执行中断的方法:
1)sh while_01.sh &
2)nohup /server/scripts/uptime.sh &
3)screen,保持会话,总结此命令
后台进程管理
TOP
top,ps,
●进程管理:(16个)总结这些命令
bg:后台运行
fg:挂起程序
jobs:显示后台程序
kill,killall,pkill:杀掉进程
crontab:设置定时
ps:查看进程
pstree:显示进程状态树
top:显示进程
nice:改变优先权
nohup:用户退出系统之后继续工作
pgrep:查找匹配条件的进程
strace:跟踪一个进程的系统调用情况
ltrace:跟踪进程调用库函数的情况
vmstat:报告虚拟内存统计信息
90)网站访问慢的案例
linux java/http/php中某一个进程占用CPU很高。
解决案例:
top -p 32311
strace -p 32311
案例文档:
http://blog.linuxeye.com/343.html
http://www.tuicool.com/articles/YFVbia
http://blog.sina.com.cn/s/blog_48eef8410101fl4p.html
ps使用的技巧
995.查看进程按内存从大到小排列
ps -e -o "%C : %p : %z : %a"|sort -k5 -nr|head -10
老男孩老师提示:
CODE NORMAL HEADER
%C pcpu %CPU
%a args COMMAND
%p pid PID
%z vsz VSZ
更多: ......
996.怎样知道某个进程在哪个CPU上运行?
ps -eo pid,args,psr
[root@oldboy ~]# ps -eo pid,args,psr
PID COMMAND PSR
1 init [3] 2
2 [migration/0] 0
3 [ksoftirqd/0] 0
4 [watchdog/0] 0
5 [migration/1] 1
6 [ksoftirqd/1] 1
7 [watchdog/1] 1
997.按cpu利用率从大到小排列
ps -e -o "%C : %p : %z : %a"|sort -nr
老-男孩老师提示:见999
998.查看进程按内存从大到小排列
ps -e -o "%C : %p : %z : %a"|sort -k5 -nr|head -10
老男孩老师提示:
CODE NORMAL HEADER
%C pcpu %CPU
%a args COMMAND
%p pid PID
%z vsz VSZ
更多:
AIX FORMAT DESCRIPTORS
This ps supports AIX format descriptors, which work somewhat like the formatting
codes of printf(1) and printf(3). For example, the normal default output can be
produced with this: ps -eo "%p %y %x %c". The NORMAL codes are described in the
next section.
CODE NORMAL HEADER
%C pcpu %CPU
%G group GROUP
%P ppid PPID
%U user USER
%a args COMMAND
%c comm COMMAND
%g rgroup RGROUP
%n nice NI
%p pid PID
%r pgid PGID
%t etime ELAPSED
%u ruser RUSER
%x time TIME
%y tty TTY
%z vsz VSZ
999.查进程已经运行了多长时间
ps -eo "%p %c %t"
[root@oldboy ~]# ps -eo pid,cmd,etime
PID CMD ELAPSED
1 init [3] 207-05:44:13
2 [migration/0] 207-05:44:12
3 [ksoftirqd/0] 207-05:44:12
范例2:通过while语句计算从1加到100之和(请用1+2+3..的方法)
#!/bin/bash
i=0
while [ $i -ne 100 ]
do
i=$(($i+1))
done
echo $i
法2
#!/bin/sh
i=1
sum=0
while ((i<101))
do
((sum = sum + i))
((i++))
done
echo $sum
法3
#!/bin/bash
i=1
sum=0
while [ $i -lt 101 ]
do
let "sum=sum+i"
let "i++"
done
echo $sum
分析日志,封掉DOS攻击
课后作业:19:38 2015/8/18
1、if语句
3、函数
4、case语句
5、while语句基础
预习:
while
for
shell数组
trap信号及跳板机
shell必会19道 本周四下午 14:00
http://oldboy.blog.51cto.com/2561410/1632876
for循环
语法
for 变量名 in 变量取值列表
do
指令
done
for 男人 in 世界
do
if [ 有房 ] && [有车] && [存款] && [会做家务] && [帅气] && [温柔] && [体贴] && [逛街买东西];then
echo "我喜欢"
else
rm -f 男人
fi
done
[root@liwx scripts]# vim for1.sh
for num in `seq 10`
do
echo $num
done
[root@liwx scripts]# sh for1.sh
1
2
3
4
5
6
7
8
9
10
范例2:获取当前目录下的目录或文件名作为变量列表打印输出
[root@liwx scripts]# cat for3.sh
#!/bin/sh
for n in `ls`
do
if [ -d $n ];then
echo "this is dir $n"
else
echo "this is file $n"
fi
done
[root@liwx scripts]# sh for3.sh
this is dir 1
this is file 2.sh
this is file ab.sh
批量改名
http://oldboy.blog.51cto.com/2561410/711342
mkdir /oldboy
cd /oldboy
touch stu_102999_{1..5}_finished.jpg
法1
[root@MySQL oldboy]# rename "_finished" "" *.jpg
[root@MySQL oldboy]# ls -l
总用量 4
-rw-r--r-- 1 root root 76 8月 18 22:23 for3.sh
-rw-r--r-- 1 root root 0 8月 18 22:24 stu_102999_1.jpg
-rw-r--r-- 1 root root 0 8月 18 22:24 stu_102999_2.jpg
-rw-r--r-- 1 root root 0 8月 18 22:24 stu_102999_3.jpg
-rw-r--r-- 1 root root 0 8月 18 22:24 stu_102999_4.jpg
-rw-r--r-- 1 root root 0 8月 18 22:24 stu_102999_5.jpg
法2
[root@MySQL oldboy]# cat for3.sh
for file in `ls *.jpg`
do
mv $file `echo $file|sed ‘s#_finished##g‘`
done
[root@MySQL scripts]# cat bak_by_db.sh
#!/bin/sh
MYUSER=root
MYPASS=oldboy123
SOCKET=/data/3306/mysql.sock
MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
BAKPATH="/server/backup/$(date +%F)"
[ ! -d $BAKPATH ] && mkdir -p $BAKPATH
for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`
do
$MYDUMP -B -x --events $dbname|gzip >$BAKPATH/${dbname}.sql.gz
if [ $? -eq 0 ];then
echo "$dbname" >>$BAKPATH/${dbname}.log
fi
done
分库分表备份
#!/bin/sh
MYUSER=root
MYPASS=liwx123
SOCKET=/data/3306/mysql.sock
MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
BAKPATH="/server/backup/$(date +%F)"
[ ! -d $BAKPATH ] && mkdir -p $BAKPATH
for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`
do
for tabname in `$MYCMD -e "use $dbname;show tables;"|sed ‘1d‘`
do
$MYDUMP -x --events ${dbname} ${tabname}|gzip >$BAKPATH/${dbname}_${tabname}.sql.gz
if [ $? -eq 0 ];then
echo "${dbname}_${tabname}" >>$BAKPATH/${dbname}.${tabname}.log
fi
done
done
设置开机自启动
for n in `chkconfig --list|grep ‘3:on‘|awk ‘{print $1}‘|egrep -v "crond|network|sshd|rsyslog"`;do chkconfig $n off;done
输出序列的方法
[root@liwx db]# seq 1 5
1
2
3
4
5
[root@liwx db]# echo {a..z}
a 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
for c语言循环
2.C语言型for循环结构
语法:
for((exp1; exp2; exp3))
do
指令...
done
例:for和while对比
[root@www scripts]# cat for03.sh
for ((i=1;i<=5;i++))
do
echo $i
done
i=1
while ((i<=5))
do
echo $i
((i++))
done
#sum=0
#!/bin/sh
计算1+2+3+..100
for ((i=1;i<=100;i++))
do
((sum+=$i))
done
echo $sum
求和尽量选择公式
[root@oldboy scripts]# echo $(( (1+100) * 100/2 ))
5050
[root@oldboy scripts]# echo $(( (1+1000000) * 1000000/2 ))
500000500000
跳出循环的方法
break 跳出循环
continue 退出当次循环
exit 退出shell
break,continue,exit区别的示例
[root@liwx for]# vim for5.sh
for((i=0; i<=5; i++))
do
if [ $i -eq 3 ] ;then
#continue;
#break;
exit
fi
echo $i
done
echo "ok"
[root@sql ~]# sh cee.sh --continue
0
1
2
4
5
ok
[root@sql ~]# sh cee.sh -----exit
0
1
2
[root@sql ~]# sh cee.sh ------break
0
1
2
ok
成产范例
1.配置多个别名IP
开发shell脚本实现给服务器临时配置多个别名IP,并可以随时撤销配置的所有IP。IP地址为:10.0.2.1-10.0.2.16,其中10.0.2.10不能配置。
配置ip命令(ifconfig/ip)提示:
ifconfig eth0:0 10.0.2.10/24 up
ifconfig eth0:0 10.0.2.10/24 down
ip addr add 10.0.2.1/24 dev eth0:0
ip addr del 10.0.2.1/24 dev eth0:0
[root@liwx for]# vim for6.sh
#!/bin/sh
IP=10.0.2
for n in {1..16}
do
if [ $n -eq 10 ];then
continue;
fi
ip addr add $IP.$n/24 dev eth0:0
done
老师的方法
[root@MySQL scripts]# cat add_ip.sh
#!/bin/sh
USAGE(){
if [ $# -ne 1 ];then
echo "$0 {start|stop}"
exit
fi
}
start(){
for ip in `seq 16`
do
if [ $ip -eq 10 ];then
continue
fi
ip addr add 10.0.2.$ip/24 dev eth0 label eth0:$ip
done
}
stop(){
for ip in `seq 16`
do
if [ $ip -eq 10 ];then
continue
fi
ip addr del 10.0.2.$ip/24 dev eth0 label eth0:$ip
done
}
main(){
case "$1" in
start)
start
;;
stop)
stop
;;
*)
USAGE
esac
}
main $*
2.批量改名
问题1:使用for循环在/oldboy目录下批量创建10个文件,名称依次为:
oldboy-1.html
oldboy-2.html
oldboy-3.html
......
oldboy-10.html
[root@liwx for]# vim for1.sh
#!/bin/sh
[ ! -d /oldboy ] && mkdir /oldboy
for n in {1..10}
do
touch /oldboy/oldboy-${n}.html
done
问题2:用for循环实现将以上文件名中的oldboy全部改成linux,并且扩展名改成大写。要求:for循环的循环体不能出现oldboy字符串。
参考:http://oldboy.blog.51cto.com/2561410/711342
[root@MySQL scripts]# cat k2.sh
cd /oldboy
for n in `ls *.html`
do
mv $n `echo $n|sed -r ‘s#^o.*y(.*)html#linux\1HTML#g‘`
done
问题3:批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码不能相同)。
数字加0的思路:
http://oldboy.blog.51cto.com/2561410/788422
3.批量创建用户并设置随机密码
问题4:批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码为随机8位字符串)。
不用for循环实现思路:
http://user.qzone.qq.com/49000448/blog/1422183723
[root@MySQL scripts]# cat adduser.sh
for n in `seq -w 10`
do
pass=`echo $RANDOM|md5sum|cut -c 2-9`
useradd oldboy$n &&\
echo $pass|passwd --stdin oldboy$n
echo -e "oldboy$n \t $pass" >>/tmp/user.log
done
以上内容的视频讲解:
企业精品shell面试题案例及专家解答精讲
http://edu.51cto.com/course/course_id-1511.html
shell数组
简单的说,数组就是相同数据类型的元素按一定顺序排列的集合.
数组就是把有限个类型元素变量或数据用一个名字命名
语法
array=(1 2 3 4 5)
或者
array=(
1
2
3
4
5)
数组的定义方法
array=(value1 value2 value3)
1)打印数组的长度
array=(1 2 3)
echo ${#array[@]} 或者 echo ${#array[*]}
[root@liwx for]# array=(1 2 3)
[root@liwx for]# echo ${#array[@]}
3
[root@liwx for]# echo ${#array[*]}
3
2)打印数组元素
[root@liwx for]# echo ${array[0]}
1
[root@liwx for]# echo ${array[1]}
2
[root@liwx for]# echo ${array[2]}
3
[root@liwx for]# echo ${array[*]}
1 2 3
[root@liwx for]# echo ${array[@]}
1 2 3
[root@MySQL scripts]# cat arr01.sh
array=(1 2 3)
for ((i=0;i<${#array[*]};i++))
do
echo ${array[i]}
done
echo ============
for i in ${array[*]}
do
echo $i
done
数组赋值
[root@test1 while]# array=(1 2 3)
[root@test1 while]# echo ${array[*]}
1 2 3
[root@test1 while]# echo ${#array[*]}
3
[root@test1 while]# array[3]=4
[root@test1 while]# echo ${#array[*]}
4
[root@test1 while]# echo ${array[*]}
1 2 3 4
[root@test1 while]# echo ${array[3]}
4
修改数组内的元素
[root@test1 while]# array[0]=liwx
[root@test1 while]# echo ${#array[*]}
4
[root@test1 while]# echo ${array[*]}
liwx 2 3 4
[root@test1 while]# echo ${array[0]}
liwx
删除赋值(删除单个值)
[root@test1 while]# unset array[0]
[root@test1 while]# echo ${array[*]}
2 3 4
删除整个数组
[root@test1 while]# unset array
[root@test1 while]# echo ${array[*]}
[root@test1 while]#
数组内容的截取和替换
截取
[root@test1 while]# array=(1 2 3 4 5)
[root@test1 while]# echo ${array[*]:2:3}
3 4 5
[root@test1 while]# echo ${array[*]:2}
3 4 5
[root@test1 while]# echo ${array[*]:1}
2 3 4 5
替换
[root@test1 while]# array=(1 2 3 4 5)
[root@test1 while]# echo ${array[*]:1}
2 3 4 5
[root@test1 while]# echo ${array[*]/2/liwx}
1 liwx 3 4 5
[root@liwx scripts]# vim arr2.sh
array=(
oldboy
zhangyue
zhangyang
)
for ((i=0;i<${#array[*]};i++))
do
echo "this is num $i,then content is ${array[$i]}"
done
echo ==================================================
echo "array len:${#array[*]}"
[root@liwx scripts]# sh arr2.sh
this is num 0,then content is oldboy
this is num 1,then content is zhangyue
this is num 2,then content is zhangyang
--------------------------
array len:3
动态数组
ls
[root@MySQL scripts]# cat array2.sh
array=($(ls))
for ((i=0;i<${#array[*]};i++))
do
echo ${array[i]}
done
echo ============
for i in ${array[*]}
do
echo $i
done
检查多个网站地址是否正常
要求:
1、shell数组方法实现,检测策略尽量模拟用户访问。
2、每10秒钟做一次所有的检测,无法访问的输出报警。
3、待检测的地址如下
http://www.etiantian.org
http://www.taobao.com
http://oldboy.blog.51cto.com
http://10.0.0.7
curl -I -s -w "%{http_code}\n" -o /dev/null www.baidu.com
wget -T 4 -q --spider ${url_list[$i]} >&/dev/null
curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}\n" www.baidu.com
200
[root@lnmp02 bbs]# curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}\n" bbs.etiantian.org
301
[root@MySQL scripts]# cat check_url.sh
#!/bin/sh
. /etc/init.d/functions
url_list=(
http://10.0.0.5
http://www.baidu.com
http://oldboy.blog.51cto.com
http://10.0.0.19
)
check_url(){
[ $# -ne 1 ] && exit 1
curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}\n" $1
}
main(){
for ((i=0;i<${#url_list[*]};i++))
do
code=`check_url ${url_list[i]}`
if [ "$code" != "200" -a "$code" != "301" ];then
action "${url_list[i]}" /bin/false
else
action "${url_list[i]}" /bin/true
fi
done
}
main $*
课后作业:19:38 2015/8/18
while
for
shell数组
预习:
shell的调试
.vimrc配置
trap信号及跳板机
kickstart无人值守批量安装
memcached服务
shell的调试
-
学习脚本开发规范
-
好的编码习惯
打游戏的思想
(第一关,第二关,第三关)
专业的脚本
函数1
函数2
main
dos2unix
bash命令参数调试
sh [-nvx] test.sh
-n: 不会执行该脚本,仅查询脚本语法是否有问题,并给出错误提示
-v: 先打印,在执行,如有错误,也会提示
-x: 将执行结果输出
set [-nvx]
小结
.vimrc
-
自动加版权信息
-
自动补全括号等
-
自动缩进
1.10.5 .vimrc vim配置代码
" ~/.vimrc
" vim config file
" date 2008-09-05
" Created by liwx
" liwx QQ:79441650
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 全局配置
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"关掉兼容模式
set nocompatible
"设置历史记录步数
set history=4000
"开启文件类型判断插件
filetype plugin on
filetype indent on
"当文件在外部被修改,自动更新该文件
set autoread
"激活鼠标的使用
set mouse=a
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 字体和颜色
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"开启语法
syntax enable
"设置字体
"set guifont=dejaVu\ Sans\ MONO\ 10
"
""设置配色
"colorscheme desert
"高亮显示当前行
set cursorline
hi cursorline guibg=#00ff00
hi CursorColumn guibg=#00ff00
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 折叠 by old1boy 21:52 2010-5-14
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"开启折叠
set nofen
set fdl=0
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 文字处理 by old1boy 21:53 2010-5-14
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"使用空格来替换tab
set expandtab
"设置所有的tab和缩进为4个空格
set tabstop=4
set shiftwidth=4
set softtabstop=4
set smarttab
"""""""""""""""""""""""""""""""""""""""""""""""""
"=>缩进 by old2boy
"""""""""""""""""""""""""""""""""""""""""""""""""
"缩进,自动缩进(继承前一行的缩进)
"set autoindent命令关闭自动缩进,是下面配置的缩写。
"可使用autoindent命令的简写,即 :set ai 和 :set noai。
"还可以使用 :set ai sw=4在一个命令中打开缩进并设置缩进级别。
set ai
"智能缩进
set si
"自动换行
set wrap
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Vim 界面 by old3boy
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Turn on WiLd menu
set wildmenu
"显示标尺
set ruler
"设置命令行的高度
set cmdheight=1
"显示行数
set nu
"Do not redraw, when running macros.. lazyredraw
set lz
"设置退格
set backspace=eol,start,indent
"Bbackspace and cursor keys wrap to
set whichwrap+=<,>,h,l
"Set magic on
set magic
"关闭遇到错误时的声音提示
set noerrorbells
set novisualbell
"显示匹配的括号([{和}])
set showmatch
"How many tenths of a second to blink
set mat=2
"高亮显示搜索的内容
set hlsearch
"搜索时不区分大小写
"还可以使用简写(:set ic 和 :set noic)
set ignorecase
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 编码设置 by oldboy 2010
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"设置编码
set encoding=gb18030
"设置文件编码
set fileencodings=gb18030
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 其他设置 by oldboy 2010
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
set smartindent
set cin
set showmatch
set guioptions-=T
set vb t_vb=
filetype on
set pastetoggle=<F9>
set background=dark
highlight Search ctermbg=black ctermfg=white guifg=white guibg=black
bashrc
Unix shell范例精解(第4版)-老男孩推荐shell书
shell-abs-3.9.1_cn
shell面试题
1.手机充值
手机充值10元,每发一次短信(输出当前余额)花费1角5分钱,当余额低于1角5分钱不能发短信,提示余额不足,请充值(可以允许用户充值继续发短信),请用while语句实现。
解答:单位换算。统一单位,统一成整数
10元=1000分,1角5分=15分
二麻子同学的方法
[root@MySQL scripts]# cat mobile_msg1.sh
#!/bin/sh
TOTAL=1000
MSG_FEE=500
function IS_NUM(){
expr $1 + 1 &>/dev/null
if [ $? -ne 0 -a "$1" != "-1" ];then
return 1
fi
return 0
}
function consum(){
read -p "Pls input your msg:" TXT
read -p "Are you to send?[y|n]" OPTION
case $OPTION in
[yY]|[yY][eE][sS])
echo "Send successfully!"
((TOTAL=TOTAL-MSG_FEE))
echo "Your have $TOTAL left!"
;;
[nN]|[nN][oO])
echo "Canceled"
;;
*)
esac
}
function charge(){
if [ $TOTAL -lt $MSG_FEE ];then
read -p "Money is not enough,Are U want to charge?[y|n]" OPT2
case $OPT2 in
y|Y)
while true
do
IS_NUM $CHARGE&&break||{
echo "INVALID INPUT"
exit 100
}
done
((TOTAL+=CHARGE)) && echo "you have $TOTAL money."
;;
n|N)
exit 101
;;
*)
echo "INVALID INPUT!"
exit 102
;;
esac
fi
}
main(){
while [ $TOTAL -ge $MSG_FEE ]
do
consum
charge
done
}
main
#!/bin/sh
sum=1000
i=15
while ((sum>=i))
do
clear
((sum=sum-i))
echo -ne "\bsend message, $sum\b"
sleep 0.2
done
clear
echo -e "\033[31;1;5mmoney is not enough:$sum\033[0m"
sleep 10
exit
李想
#!/bin/bash
i=1000
until [ $i -lt 15 ]
do
((i=i-15))
echo "the message:$i"
if [ $i -lt 15 ];then
echo "your money is left $i,余额不足"
read -p "pls Recharge money:" num
i=$(($num+$i))
fi
done
刘铮
#!/bin/sh
huafei=1000
i=0
SENDMESSGE(){
while [ $huafei -gt 960 ]
do
huafei=$[$huafei-15]
let i++
sleep 1
echo "当前余额:$huafei,您累计发送短信 $i 条"
done
echo "余额不足,请充值!"
read -p "请输入您要充值的金额:" chongzhi
huafei=$[$huafei+$chongzhi]
echo "您已成功充值,余额为:$huafei."
SENDMESSGE
}
SENDMESSGE
2.猜数字
首先让系统随机生成一个数字,给这个数字定一个范围(数字前50及后50),让用户输入猜的数字,对输入判断,如果不符合数字就给予高与低的提示,根据提示,看你多少次可以猜对?
[root@liwx scripts]# vim caishuzi.sh
#!/bin/bash
NUM=$(date +%S)
echo "当前苹果价格是每斤$NUM元"
echo "========================"
sleep 1
clear
ipple(){
echo ‘这苹果多少钱一斤啊?
请猜0-60的数字‘
read -p "请输入你的价格:" A
expr $A + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "别逗我了,快猜数字"
ipple
fi
}
guess(){
if [ $A -eq $NUM ]
then
echo "猜对了,就是$NUM元"
exit 0
elif [ $A -gt $NUM ]
then
echo "嘿嘿,要不你用这个价买?"
ipple
elif [ $A -lt $NUM ]
then
echo "太低太低"
ipple
fi
}
main(){
ipple
while true
do
guess
done
}
main
3.分析apache日志
问题1:计算apache一天的日志access_2010-12-8.log中所有行的日志各元素的访问字节数的总和。给出实现程序。练习日志:见目录下access_2010-12-8.log,也可以用自己的apache日志。请用while循环实现。(3分钟)
拓展:while按行读文件的方式:
方式1:
exec <FILE
sum=0
while read line
do
cmd
done
方式2:
cat ${FILE_PATH} | while read line
do
cmd
done
方式3:
while read line
do
cmd
done<FILE
[root@MySQL scripts]# cat sum-while.sh
sum=0
while read line
do
value=`echo $line|awk ‘{print $10}‘`
expr $value + 1 &>/dev/null
[ $? -ne 0 ] && continue
((sum+=value))
done<access_2010-12-8.log
echo $sum
4.解决DOS攻击
企业实战题6:请用至少两种方法实现!
写一个脚本解决DOS攻击生产案例
提示:根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔3分钟。防火墙命令为:iptables -A INPUT -s 10.0.1.10 -j DROP。
方法1
[root@liwx dos]# vim check_dos.sh
#!/bin/sh
awk ‘{print $1}‘ /service/scripts/dos/access_2010-12-8.log |sort -t "." -k 4|uniq -c >/tmp/dos_ip.log
exec </tmp/dos_ip.log
while read line
do
NUM=`echo $line|awk ‘{print $1}‘`
IP=`echo $line|awk ‘{print $2}‘`
IPTAB=`iptables -L -n|grep "$IP"|wc -l`
if [ "$NUM" -gt "3" ]&&[ "$IPTAB" -lt "1" ]
then
iptables -I INPUT -s $IP -j DROP
echo "$IP is dropped" >>/opt/iptab_doop_ip.log
fi
done
方法2
[root@mysql 19_shell]# cat check1.sh
#!/bin/sh
while true
do
netstat -an|grep EST|awk -F "[ :]+" ‘{print $6}‘|sort |uniq -c>/opt/c.log
exec</opt/c.log
while read line
do
pv=`echo $line|awk ‘{print $1}‘`
ip=`echo $line|awk ‘{print $2}‘`
if [ $pv -gt 3 ]&&[ `iptables -L -n|grep $ip |wc -l -eq 0` ]
then
iptables -A INPUT -s $ip -j DROP
echo "$ip has jopped">>/tmp/droplist.log
fi
done
sleep 180
done
iptables主要参数
-A 向规则链中添加一条规则,默认被添加到末尾
-T指定要操作的表,默认是filter
-D从规则链中删除规则,可以指定序号或者匹配的规则来删除
-R进行规则替换
-I插入一条规则,默认被插入到首部
-F清空所选的链,重启后恢复
-N新建用户自定义的规则链
-X删除用户自定义的规则链
-p用来指定协议可以是tcp,udp,icmp等也可以是数字的协议号,
-s指定源地址
-d指定目的地址
-i进入接口
-o流出接口
-j采取的动作,accept,drop,snat,dnat,masquerade
--sport源端口
--dport目的端口,端口必须和协议一起来配合使用
5.监控mysql主从
企业面试题1:(生产实战案例):监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理员。提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟:
阶段1:开发一个守护进程脚本每30秒实现检测一次。
阶段2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。
阶段3:请使用数组技术实现上述脚本(获取主从判断及错误号部分)
[root@MySQL-master-02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock -e "show slave status\G;" *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.1.51 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 107 Relay_Log_File: relay-bin.000013 Relay_Log_Pos: 253 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: mysql Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 107 Relay_Log_Space: 549 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 |
解答: #!/bin/sh
while true do error=(1158 1159 1008 1007 1062 1236) #CMD="mysql -uroot -poldboy123 -S /data/3307/mysql.sock" CMD=`cat /service/scripts/mysql/mysql.log |egrep "Running|Behind_Master|Last_SQL_Errno"|awk ‘{print $2}‘` #array2=($($CMD -e "show slave status\G"|egrep "Running|Behind_Master|Last_SQL_Errno"|awk ‘{print $NF}‘)) array2=($CMD) if [ "${array2[0]}" == "Yes" -a "${array2[1]}" == "Yes" -a "${array2[2]}" == "0" ];then echo "mysql slave is OK" else for i in ${error[*]} do if [ "${array2[3]}" == "$i" ];then #$CMD -e "stop slave;set global sql_slave_skip_counter=1;start slave;" sed -i ‘s#SQL_Errno:.*$#SQL_Errno: 0#g‘ /service/scripts/mysql/mysql.log echo $i fi done echo "slave is not OK" echo "slave is not OK"|mail -s "error about slave info $(date +%F_%R)" 79441650@qq.com fi sleep 50 done |
王二麻的方法
#!/bin/bash
###########################################
# File Name: mon_mysql.sh
# Author: Troy
# mail: troy@trnux.com
# Created Time: 2015年08月17日 星期一 09时35分07秒
#########################################
#Define vars
REPORT_FILE=/app/logs/mon_mysql/error.log
MYSQL_HOST="192.168.16.102"
MASTER_PORT=3306
SLAVE_PORT=3307
MYSQL_USER="monitor"
MYSQL_PWD="123456"
ERR_CODE_ARR=(1158 1159 1008 1007 1062)
MYSQL_CMD="mysql -h $MYSQL_HOST -P $SLAVE_PORT -u $MYSQL_USER -p$MYSQL_PWD"
[ ! -d `dirname $REPORT_FILE` ]&&mkdir `dirname $REPORT_FILE` -p
function report(){
#accept STRING as $1
echo "`date +%F_%T`:$1"|tee -a $REPORT_FILE
}
function rec_mysql(){
#accept error code as $1
#1158,1159,1008,1007,1062
ERR_CODE=$1
echo ${ERR_CODE_ARR[@]}|grep -w "$ERR_CODE" &>/dev/null
if [ $? -eq 0 ];then
SQL_QUERY="stop slave;set global sql_slave_skip_counter = 1;start slave;"
$MYSQL_CMD -e "$SQL_QUERY"
report "Err $ERR_CODE has been solved!"
return 0
else
report "Please Handle Error $ERR_CODE Mannuallly!"
return 1
fi
}
function check_rep(){
#generate mysql info arr
MYSQL_INFO_ARR=(`$MYSQL_CMD -e "show slave status\G"|grep -iE "running|behind|last_errno"|sed -r ‘s#\s+##g‘`)
#echo arr for debugging
echo ${MYSQL_INFO_ARR[@]}
#handle err code
if [ ${MYSQL_INFO_ARR[0]#*:} != "Yes" -o ${MYSQL_INFO_ARR[1]#*:} != "Yes" ]
then
report "MySQL_REPLICATION doen‘t work!"
rec_mysql ${MYSQL_INFO_ARR[2]#*:}
return 1
elif [ ${MYSQL_INFO_ARR[3]#*:} -ne 0 ]
then
report "Take Care,Slave is lagged!"
else
echo "MySQL Replication is Healthy!"
break
fi
return 0
}
function check_srv(){
echo "\n"|telnet $MYSQL_HOST $MASTER_PORT 2>/dev/null|grep -i "connected" &>/dev/null
if [ $? -ne 0 ];then
report "MySQL Master Doesn‘t Work!Check it"
return 1
fi
echo "\n"|telnet $MYSQL_HOST $SLAVE_PORT 2>/dev/null|grep -i "connected" &>/dev/null
if [ $? -ne 0 ];then
report "MySQL Slave Doesn‘t Work!Check it"
return 1
fi
return 0
}
function main(){
while true
do
check_srv
while [ $? -eq 0 ]
do
check_rep
done
sleep 5
done
}
main
6.批量创建随机数文件
企业面试题2:使用for循环在/oldboy目录下通过随机小写10个字母加固定字符串oldboy批量创建10个html文件,名称例如为:
[root@oldboy oldboy]# sh /server/scripts/oldboy.sh
[root@oldboy oldboy]# ls
coaolvajcq_oldboy.html qnvuxvicni_oldboy.html vioesjmcbu_oldboy.html
gmkhrancxh_oldboy.html tmdjormaxr_oldboy.html wzewnojiwe_oldboy.html
jdxexendbe_oldboy.html ugaywanjlm_oldboy.html xzzruhdzda_oldboy.html
qcawgsrtkp_oldboy.html vfrphtqjpc_oldboy.html
解答:
- 先判断oldboy目录是否存在,不存在则创建
#!/bin/sh
[ ! -d /oldboy ]&& mkdir /oldboy
cd /oldboy
2.随机小写10个字母
[root@mysql ~]# tr -dc "a-z"</dev/urandom|head -c 10
vfmiiqlobi
head -c <字节> 显示字节数
随机字符生成单词
tr 替换字符串 -c str1的补集 d 删除str1的字符 dc表示删除str1的补集字符,即保留str1字符
/dev/random存储系统当前运行的环境的实时数据,可以看作系统某时候的唯一值数据,提供优质随机数。实测出不了结果
/dev/urandom是非阻塞的随机数产生器,读取时不会产生阻塞,速度更快、安全性较差的随机数发生器。
扩展:
可通过读取Linux的uuid码
UUID码全称是通过唯一识别码,UUID格式是:包含32个16进制数字,以"_"连接号分为五段,形式为8-4-4-4-12的32个字符。Linux的uuid码也是由内核提供的,在/proc/sys/kernel/random/uuid这个文件内。cat /proc/sys/kernel/random/uuid每次获取到的数据都会不同。
数字加字母的随机数
[root@mysql ~]# cat /proc/sys/kernel/random/uuid| md5sum | cut -c 1-10
f4365be7c3
1)生成随机数(0-32767)
[root@liwx ~]# echo $RANDOM
14436
[root@liwx ~]# echo $RANDOM
24119
[root@liwx ~]# echo $RANDOM
31196
2)取8位数字随机数
[root@liwx ~]# echo $((RANDOM**3))
3220809592832
[root@liwx ~]# echo $((RANDOM**3))|cut -c 1-8
94380757
3)取8位随机md5值
[root@oldboy scripts]# echo $RANDOM|md5sum|cut -c 2-9
ef8e0175
解答脚本
#!/bin/sh
[ ! -d /oldboy ]&& mkdir /oldboy
cd /oldboy
for i in `seq 10`
do
#RAN=`tr -dc "a-z"</dev/urandom|head -c 10`
RAN=`echo $RANDOM|md5sum|cut -c 2-11|tr [0-9] [a-j]`
touch "$RAN"_liwx.html
#touch ${$RAN}_liwx.html
done
7.批量改名
企业面试题3:请用至少两种方法实现!
将以上文件名中的oldboy全部改成oldgirl(用for循环实现),并且html改成大写。
[root@liwx oldboy]# echo sed.sh
sed.sh
[root@liwx oldboy]# echo sed.sh |sed ‘s#sed#abc#g‘
abc.sh
[root@liwx oldboy]# mv sed.sh `echo sed.sh |sed ‘s#sed#abc#g‘`
[root@liwx oldboy]# ls
abc.sh
法1
#!/bin/sh
[ ! -d /oldboy ]&& exit
cd /oldboy
for i in `ls *.html`
do
mv $i `echo $i|sed ‘s#liwx.html#old.HTML#g‘`
done
法2
rename old.HTML liwx.html *.HTML
8.批量创建账号,并设置密码
企业面试题4:
批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码为随机8位字符串)。
[root@liwx user]# vim mkuser.sh
#!/bin/sh
for i in `seq -w 10`
do
pass=`echo $RANDOM|md5sum|cut -c 1-8`
useradd liwx$i &&
echo $pass|passwd --stdin liwx$i
echo -e "liwx$i\t $pass" >>/tmp/pass.txt
done
[root@liwx tmp]# cat /tmp/pass.txt
liwx01 5d400854
liwx02 81ef73c2
liwx03 62688d37
liwx04 6eea713a
liwx05 dac54109
liwx06 50299937
liwx07 fbfb118a
liwx08 76ec371b
liwx09 a92d9ac1
liwx10 e4fe29ea
扩展
seq -w 指定输出数字同宽,前面不足的用0补全,即与位数最多的数对齐
echo -e 处理特殊字符
若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:
\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\\ 插入\字符;
\nnn 插入nnn(八进制)所代表的ASCII字符;
seq -w 指定输出数字同宽,前面不足的用0补全,即与位数最多的数对齐
echo -e 处理特殊字符
若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:
\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\\ 插入\字符;
\nnn 插入nnn(八进制)所代表的ASCII字符;
9.判断在线IP
企业面试题5:
写一个脚本,实现判断10.0.0.0/24网络里,当前在线用户的IP有哪些(方法有很多)
|
#!/bin/sh
. /etc/init.d/functions for n in {140..160} do { ping -c 1 -W 1 192.168.203.$n &>/dev/null if [ "$?" -eq "0" ];then echo -e "\033[32m192.168.203.$n is ONLINE\033[0m `action "" /bin/true`" echo "192.168.203.$n" >>/tmp/online.txt else echo -e "\033[31m192.168.203.$n is OFFLINE\033[0m `action "" /bin/false`" echo "192.168.203.$n" >>/tmp/unline.txt fi }& done wait
|
10.mysql多实例启动脚本
企业实战题7:
开发mysql多实例启动脚本:
已知mysql多实例启动命令为:mysqld_safe --defaults-file=/data/3306/my.cnf &
停止命令为:mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown
请完成mysql多实例启动启动脚本的编写
要求:用函数,case语句、if语句等实现。
我的方法
#!/bin/sh
# chkconfig: 2345 20 80
# description: start mysql and stop mysql scripts.
. /etc/init.d/functions
port="3306"
path="/application/mysql/bin"
user="root"
pass="liwx123"
sock="/data/$port/mysql.sock"
cnf="/data/$port/my.cnf"
USAGE(){
echo "PLEASE USAGE: $0 {start|stop|restart|status}"
}
start(){
if [ `ss -lntup|grep "$port"|wc -l` -ne "1" ];then
#print "starting MySQL.........\n"
$path/mysqld_safe --defaults-file=$cnf &>/dev/null &
action "Starting $port/mysql......." /bin/true
else
echo "$port/mysql is running........."
fi
}
stop(){
if [ `ss -lntup|grep "$port"|wc -l` -ne "1" ];then
echo "$port/mysql is stopped........."
else
$path/mysqladmin -u$user -p$pass -S $sock shutdown &>/dev/null
action "Stoping $port/mysql......." /bin/true
fi
}
restart(){
stop
sleep 2
start
}
status(){
if [ `ss -lntup|grep "$port"|wc -l` -ne "1" ];then
echo "$port/mysql is stopping"
else
echo "$port/mysql is running"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
USAGE
esac
谢迪的方法
#!/bin/sh
# description: start mysql and stop mysql scripts.
. /etc/init.d/functions
path=/application/mysql/bin/
user="root"
pass="oldboy123"
sock="/data/3306/mysql.sock"
pos="/data/3306/my.cnf"
USAGE(){
echo "USAGE: $0 {start|stop|restart}"
}
start_mysql(){
$path/mysqld_safe --defaults-file=$pos &>/dev/null &
if [ $? -eq 0 ];then
action "mysql start" /bin/true
else
action "mysql start" /bin/false
fi
}
stop_mysql(){
$path/mysqladmin -u$user -p$pass -S $sock shutdown &>/dev/null
if [ $? -eq 0 ];then
action "mysql stop" /bin/true
else
action "mysql stop" /bin/false
fi
}
restart_mysql(){
stop_mysql
sleep 3
start_mysql
}
case "$1" in
start)
start_mysql
RETVAL=$?
;;
stop)
stop_mysql
RETVAL=$?
;;
restart)
stop_mysql
start_mysql
RETVAL=$?
;;
*)
USAGE
exit 1
esac
exit $RETVAL:
加入开机启动项
[root@mysql shell_job]# cp mysql /etc/init.d/mysql
[root@mysql shell_job]# chmod +x /etc/init.d/mysql
[root@mysql shell_job]# chkconfig --add mysql
[root@mysql shell_job]# chkconfig mysql on
[root@mysql shell_job]# chkconfig --list mysql
mysql 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@mysql shell_job]# chkconfig mysql off
[root@mysql shell_job]# chkconfig --list mysql
mysql 0:off 1:off 2:off 3:off 4:off 5:off 6:off
法2
#!/bin/bash
port=3306
mysql_user="root"
mysql_pwd="lixiang123"
Cmdpath=/usr/local/mysql/bin
mysql_sock="/tmp/mysql.sock"
#start function
function_start_mysql()
{
if [ `netstat -lntup|grep "$port"|wc -l` -ne 1 ];then
printf "Starting Mysql.....\n"
/bin/sh ${Cmdpath}/mysql_safe --defaults-file=/etc/my.cnf >/dev/null 2>&1
else
printf "mysql is running....."
fi
}
#stop function
function_stop_mysql()
{
if [ `netstat -lntup|grep "$port"|wc -l` -ne 1 ];then
printf "mysql is stopped...\n"
exit
else
printf "stoping mysql....\n"
${Cmdpath}/mysqladmin -u${mysql_user} -p${mysql_pwd} -S /tmp/mysql.sock shudown
fi
}
#restart function
function_restart_mysql()
{
printf "reasting mysql....\n"
function_stop_mysql
sleep 2
function_start_mysql
}
case "$1" in
start)
function_start_mysql
;;
stop)
function_stop_mysql
;;
restart)
function_restart_mysql
;;
*)
printf "Usage:/tmp/mysql.sock/mysql {start|stop|restart}\n"
esac
法3
#!/bin/sh
#chkconfig: 2345 56 24
#description: This is about rysnc restart shell
. /etc/init.d/functions
RETVAL=0
prog=mysql
lockfile=/var/lock/subsys/mysql
#[ $UID -eq 0 ] && [ -e /data/3306/my.cnf ] && . /data/3306/my.cnf
start(){
if [ $UID -ne 0 ];then
echo "User has insuffcient privilege."
exit 4
fi
if [ ! -f /data/3306/mysql.pid ];then
/application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf &>/dev/null &
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $lockfile &&
action "Starting $prog......" /bin/true
fi
}
stop(){
#kill `cat /application/nginx/logs/nginx.pid`
/application/mysql/bin/mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown &>/dev/null
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $lockfile
action "Stopping $prog......" /bin/true
}
restart(){
start
stop
}
status(){
if [ -e $lockfile ];then
echo $prog is running
else
echo "${prog} is not running"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
*)
echo "USAGE:$0 {start|stop|restart}"
esac
11.mysql分库分表备份
企业实战题8:如何实现对MySQL数据库进行分库备份,请用脚本实现
分库备份的脚本
[root@MySQL scripts]# cat bak_by_db.sh
#!/bin/sh
MYUSER=root
MYPASS=oldboy123
SOCKET=/data/3306/mysql.sock
MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
BAKPATH="/server/backup/$(date +%F)"
[ ! -d $BAKPATH ] && mkdir -p $BAKPATH
for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`
do
$MYDUMP -B -x --events $dbname|gzip >$BAKPATH/${dbname}.sql.gz
if [ $? -eq 0 ];then
echo "$dbname" >>$BAKPATH/${dbname}.log
fi
done
分库分表备份
#!/bin/sh
MYUSER=root
MYPASS=liwx123
SOCKET=/data/3306/mysql.sock
MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
BAKPATH="/server/backup/$(date +%F)"
[ ! -d $BAKPATH ] && mkdir -p $BAKPATH
for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`
do
for tabname in `$MYCMD -e "use $dbname;show tables;"|sed ‘1d‘`
do
$MYDUMP -x --events ${dbname} ${tabname}|gzip >$BAKPATH/${dbname}_${tabname}.sql.gz
if [ $? -eq 0 ];then
echo "${dbname}_${tabname}" >>$BAKPATH/${dbname}.${tabname}.log
fi
done
done
李想的方法
分库
#!/bin/sh
myuser=root
mypasswd=liwx123
socket=/tmp/mysql.sock
mycmd="mysql -u$myuser -p$mypasswd -S $socket"
mydump="mysqldump -u$myuser -p$mypasswd -S $socket"
for database in `$mycmd -e "show databases;"|sed ‘1,2d‘|egrep -v "mysql|performance_schema"`
do
$mydump $database|gzip >/data/backup/${database}_$(date +%F)_sql.gz
done
分库分表
#!/bin/sh
myuser=root
mypasswd=lixiang123
socket=/tmp/mysql.sock
mycmd="mysql -u$myuser -p$mypasswd -S $socket"
mydump="mysqldump -u$myuser -p$mypasswd -S $socket"
for database in `$mycmd -e "show databases;"|sed ‘1,2d‘|egrep -v "mysql|performance_schema"`
do
for tables in `mydump -e "show tables from $databses;"|sed ‘1d‘`
do
$mydump $database $tables|gzip >/data/backup/${database}/${databse}_${tables}_$(date +%F)_sql.gz
done
done
12.打印字母数不大于6的单词
企业面试题10:请用至少两种方法实现!
bash for循环打印下面这句话中字母数不大于6的单词(昆仑万维面试题)。
I am oldboy teacher welcome to oldboy training class.
求字符串长度常用的三种方法:
expr length "$OLDBOY"
echo $OLDBOY|wc -L
echo ${#OLDBOY}
我的方法
[root@gw for]# vim bi_daxiao.sh
#!/bin/sh
for i in I am oldboy teacher welcome to oldboy training class
do
#if [ `echo $i|wc -L` -lt 6 ];then
if [ "${#i}" -lt "6" ];then
echo $i
fi
done
echo ==========================================================
arr=(I am oldboy teacher welcome to oldboy training class)
for i in ${arr[*]}
do
if [ ${#i} -lt 6 ];then
echo $i
fi
done
方法一:
#!/bin/bash
for i in I am oldboy teacher welcome to oldboy training class
do
if [ `echo $i|wc -L` -lt 6 ]
then
echo $i
fi
done
方法二:
echo "I am oldboy teacher welcome to oldboy training class"|awk ‘{for(i=1;i<=NF;i++) if(length($i)<6 ) print $i}‘
方法三:
array=(I am oldboy teacher welcome to oldboy training class)
for i in ${array[*]}
do
if [ `expr length $i` -lt 6 ];then
echo $i
fi
done
方法四:
#!/bin/bash
arr=(I am oldboy teacher welcome to oldboy training class)
for((i=0;i<${#arr[*]};i++))
do
if [ ${#arr[i]} -le 6 ]
then
echo ${arr[i]}
fi
done
13.比较2个整数大小
企业面试题11:开发shell脚本分别实现以脚本传参以及read读入的方式比较2个整数大小。以屏幕输出的方式提醒用户比较结果。注意:一共是开发2个脚本。当用脚本传参以及read读入的方式需要对变量是否为数字、并且传参个数做判断。
我的方法read
[root@gw for]# vim bi_daxiao.sh
#!/bin/sh
read -p "Please input two number:" a b
expr $a + $b + 1 &>/dev/null
RETVAL=$?
[ $RETVAL -ne 0 ]&& echo "ple input two number"||
if [ "$a" -lt "$b" ];then
echo "$a < $b"
elif [ "$a" -gt "$b" ];then
echo "$a > $b"
elif [ "$a" -eq "$b" ];then
echo "$a = $b"
else
echo "ple input two number"
fi
传参方式
[root@gw for]# vim bi_dx_02.sh
#!/bin/sh
a=$1
b=$2
#no.1
if [ $# -ne 2 ];then
echo "USAGE: sh $0 numb1 numb2"
exit
fi
expr $a + $b + 1 &>/dev/null
RETVAL=$?
if [ $RETVAL -ne 0 ];then
echo "ple input two number"
exit
fi
#no.2
if [ $a -gt $b ];then
echo "$a > $b"
elif [ $a -lt $b ];then
echo "$a < $b"
else
echo "$a = $b"
fi
#!/bin/bash
first=$1
second=$2
echo $first
echo $second
if [ $1 -eq $2 ]
then
echo "the result is equal"
fi
if [ $1 -lt $2 ]
then
echo "$1小于$2"
else
echo "$1大于$2"
fi
14.菜单,一键安装web服务
企业面试题12:打印选择菜单,一键安装Web服务:
[root@oldboyscripts]# sh menu.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
要求:
1、当用户输入1时,输出"startinstalling lamp."然后执行/server/scripts/lamp.sh,脚本内容输出"lamp is installed"后退出脚本;
2、当用户输入2时,输出"startinstalling lnmp."然后执行/server/scripts/lnmp.sh输出"lnmp is installed"后退出脚本;
3、当输入3时,退出当前菜单及脚本;
4、当输入任何其它字符,给出提示"Input error"后退出脚本。
5、要对执行的脚本进行相关条件判断,例如:脚本是否存在,是否可执行等。
我的方法
#!/bin/sh
menu(){
cat <<EOF
----------------------------------------
|****Please Enter Your Choice:[0-3]****|
----------------------------------------
1.[install lamp]
2.[install lnmp]
3.[exit]
EOF
}
lamp(){
echo "startinstalling lamp.."
[ -f /service/scripts/lamp.sh ]&&
/bin/sh /service/scripts/lamp.sh||
echo "instlling lamp.sh error"
}
lnmp(){
echo "startinstalling lnmp.."
[ -f /service/scripts/lnmp.sh ]&&
/bin/sh /service/scripts/lnmp.sh||
echo "instlling lnmp.sh error"
}
exit1(){
echo "byebye!!"
exit
}
menu1(){
read -p "please input a number:" a
case "$a" in
1)
lamp
sleep 2
clear
;;
2)
lnmp
sleep 2
clear
;;
3|exit)
clear
exit1
;;
*)
echo "input error,please input [1-3]"
sleep 1
menu
esac
}
while true
do
clear
menu
menu1
done
简单的方法
[root@mysql scripts]# cat caidan.sh
#!/bin/sh
#no1
cat <<EOF
1.[install lamp]
2.[install lnmp]
3.[exit]
EOF
#no2
read -p "pls input the num you want:" a
if [ $a != 1 ] &&[ $a != 2 ]&&[ $a != 3 ]
then
echo "Input error"
exit 1
fi
#no3
if [ $a -eq 1 ]
then
echo "startinstalling lamp."
[ -f /server/scripts/lamp.sh ]&&[ -x /server/scripts/lamp.sh ]&&
/bin/sh /server/scripts/lamp.sh
exit
fi
if [ $a -eq 2 ]
then
echo "startinstalling lnmp."
[ -f /server/scripts/lnmp.sh ]&&[ -x /server/scripts/lnmp.sh ]&&
/bin/sh /server/scripts/lnmp.sh &>/dev/null
exit
fi
if [ $a -eq 3 ]
then
echo "byebye!!"
exit
fi
李想的方法
#!/bin/bash
echo -e "\033[32m========================================\033[0m"
echo -e "\033[32m The Author : lx \033[0m"
echo -e "\033[32m Description:lamp/lnmp \033[0m"
echo -e "\033[32m QQ:695915099 \033[0m"
echo -e "\033[32m========================================\033[0m"
menu(){
cat << EOF
----------------------------------------
|****Please Enter Your Choice:[0-3]****|
----------------------------------------
1.[install lamp]
2.[install lnmp]
3.[exit]
EOF
}
menu1(){
cat << EOF
----------------------------------------
|****Please Enter Your Choice:[0-4]****|
----------------------------------------
1.[install apache]
2.[install php]
3.[install mysql]
4.[back]
EOF
}
menu2(){
cat << EOF
----------------------------------------
|****Please Enter Your Choice:[0-4]****|
----------------------------------------
1.[install nginx]
2.[install php]
3.[install mysql]
4.[back]
EOF
}
lamp(){
clear
while true
do
menu1
read -p "please input a number:" num1
case "$num1" in
1)
echo -e "\033[32mThe Apache is installing......\033[0m"
sleep 3
;;
2)
echo -e "\033[32mThe Php is installing......\033[0m"
sleep 3
;;
3)
echo -e "\033[32mThe Mysql is installing......\033[0m"
sleep 3
;;
4)
clear
break
;;
*)
esac
done
}
lnmp(){
clear
while true
do
menu2
read -p "please input a number:" num2
case "$num2" in
1)
echo -e "\033[32mThe Nginx is installing......\033[0m"
sleep 3
;;
2)
echo -e "\033[32mThe Php is installing......\033[0m"
sleep 3
;;
3)
echo -e "\033[32mThe Mysql is installing......\033[0m"
sleep 3
;;
4)
clear
break
;;
*)
esac
done
}
declare flag=0
while [ "$flag" -eq 0 ]
do
menu
while true
do
read -p "pls input the you want:" num
expr $num + 1 &>/dev/null
REVGRS=$?
[ $REVGRS -ne 0 ] &&{
echo "pls input a intger number!"
exit 1
}
[ $num -eq 1 ] && {
lamp
}
[ $num -eq 2 ] && {
lnmp
}
[ $num -eq 3 ] && {
exit
}
break
done
##############################################
[ $num -ge 4 ] && {
echo -e "\033[32mplease select 1 or 2 or 3\033[0m"
menu
read -p "pls input the you want:" num3
[ $num3 -eq 1 ] && {
lamp
}
[ $num3 -eq 2 ] && {
lnmp
}
[ $num3 -eq 3 ] && {
exit
}
}
done
15.监控web服务
企业面试题13:
1、监控web服务是否正常,不低于3种监控策略。
2、监控db服务是否正常,不低于3种监控策略。
要求间隔1分钟,持续监控。web:
监控网站异常最简单的可以以端口是不是通畅,是不是打开为目标,监控端口有2种方式,第一种,如果在本地监控的话可以用ss netstat lsof第二种,如果在监控服务器上远程监控客户端web服务器可以通过telnet nmap nc这样的方式,端口的监控只是一般的监控,端口通畅了不代表服务是好的,它只是一个必要条件,但是监控端口比较简单,所以在常规情况下这个必要条件我们可能也会用,并且我们还会用其他的端口监控方式,那就是,进程数,通过ps看一下本地的进程数,然后来判断,这种方式的缺点就是只适合在本地监控,另外我们可以通过header这种远程本地都适合的方式看看返回值是否为200,来进行监控,另外最好的监控方式就是模拟用户的方式,就是说用户怎么认为不正常我们就用什么方式来监控,这种方式第一个是wget ,第二个是curl 第三个我们可以用php 程序去写监控,这个是最好的方式。
总的来说:监控有端口,进程,header ,wget ,curl,php最后2个是准确度最高的,企业里面我们常用的就是端口+应用程序,或者是wget 和curl的形式。
1.根据进程数判断
[root@lnmp ~]# cat check_web.sh
#!/bin/sh
while true
do
if [ `ps -ef |grep nginx|egrep -v "php-fpm|grep"` -ge 2 ];then
echo "nginx is running"
else
echo "nginx is stopped"
/application/nginx/sbin/nginx
fi
sleep 60
done
2.根据端口判断
[root@lnmp ~]# cat check_web1.sh
#!/bin/sh
while true
do
if [ `lsof -i:80|grep "nginx"|wc -l` -ge 2 ];then
echo "Nginx is running"
else
echo "Nginx is stopped"
/application/nginx/sbin/nginx
fi
sleep 60
done
3.使用wget和curl方式
curl示例
[root@gw caidan]# curl -I -s -w "%{http_code}\n" www.baidu.com -o /dev/null
200
脚本
[root@lnmp ~]# cat check_web1.sh1
#!/bin/sh
while true
do
if [ "`curl -I -s -w "%{http_code}\n" 10.0.0.225 -o /dev/null`" != "200" ];then
echo "httpd is not running"
else
echo "httpd is running"
fi
sleep 60
done
wget示例
[root@gw caidan]# wget -T 10 --spider -t 2 www.baidu.com
[root@gw caidan]# echo $?
0
脚本
[root@lnmp ~]# cat check_web1.sh2
#!/bin/sh
while true
do
port=`wget -T 10 --spider -t 2 10.0.0.225 &>/dev/null`
if [ $? -ne 0 ];then
echo "httpd is not running"
else
echo "httpd is running"
fi
sleep 60
done
方法2
#!/bin/bash
while true
do
wget --spider --timeout=2 --tries=2 $1 &>/dev/null
if [ $? -ne 0 ];then
echo "web is error"
else
echo "web is ok"
fi
sleep 60
done
4.监控MySQL
[root@lnmp ~]# cat check_db01.sh
#!/bin/sh
while true
do
if [ "`ss -lnt|grep 3306|awk -F "[ |:]+" ‘{print $5}‘`" == "3306" ]
#if [ `lsof -i tcp:3306|wc -l` -gt 0 ]
if [ `ps -ef|grep mysql|grep -v grep|wc -l` -gt 0 ]
if [ ` nmap 10.0.0.7 -p 3306|grep "open"|wc -l` -gt 0 ]
#if [ `nc -w 2 10.0.0.7 3306 &>/dev/null&&echo ok|grep ok|wc -l` -gt 0 ]
then
echo "mysql is running"
else
echo "mysql is stopped."
/data/3306/mysql start
fi
sleep 60
done
李想
#!/bin/sh
if [ "`netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘`" = "3306" ]
#cuo-if [ `netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘` -eq 3306 ]
#if [ `ps -ef|grep mysql|grep -v grep|wc -l` -gt 0 ]
#if [ `nc -w 2 10.0.0.7 3306 &>/dev/null&&echo ok|grep ok|wc -l` -gt 0 ]
#if [ `nmap 10.0.0.7 -p 3306 2>/dev/null|grep open|wc -l` -gt 0 ]
#if [ `netstat -lntup|grep mysqld|wc -l` -gt 0 ]
#if [ `lsof -i tcp:3306|wc -l` -gt 0 ]
then
echo "MySQL is Running."
else
echo "MySQL is Stopped."
/data/3306/mysql start
fi
16.监控memcache服务
企业面试题14:监控memcache服务是否正常,模拟用户(web客户端)检测。
使用nc命令加上set/get来模拟检测,以及监控响应时间及命中率。
水电费第三方
17.监控文件是否被恶意篡改
企业面试题15:面试及实战考试题:监控web站点目录(/var/html/www)下所有文件是否被恶意篡改(文件内容被改了),如果有就打印改动的文件名(发邮件),定时任务每3分钟执行一次(10分钟时间完成)。
解答:过程
-
大小可能会变化
-
修改时间会变化
-
文件内容会变化,md5指纹
-
增加或者删除文件
find /data/html/bbs/ -type f|xargs md5sum >/server/scripts/md5/md5.`date +%F_%R`.log
思路:
1.文件被修改 用md5指纹
2.文件数量变化 用diff对比
我的方法
#!/bin/sh
path=/data/html/bbs
md5_log=/server/scripts/md5/md5.2015-09-25_01:40.log
old_num=/server/scripts/md5/num.2015-09-25_02:29.log
err01_log=/tmp/md5_err01.log
err02_log=/tmp/md5_err02.log
[ ! -f $err01_log ]&& touch $err01_log
[ ! -f $err02_log ]&& touch $err02_log
while true
do
fail_md5=`md5sum -c $md5_log 2>/dev/null|grep FAILED`
check_md5=`md5sum -c $md5_log 2>/dev/null|grep FAILED|wc -l`
find $path -type f >/tmp/new_md5.log
if [ "$check_md5 -ne 0" ] || [ `cat $old_num|wc -l` -ne `cat /tmp/new_md5.log|wc -l` ]
then
echo $fail_md5 >$err01_log
diff $old_num /tmp/new_md5.log >$err02_log
#mail -s "cuangai bbs $(date)" 79441650@qq.com
cat $err01_log $err02_log
fi
sleep 5
done
李想
find /var/html/www -type f -mtime 0|xargs md5sum > lx01.log 【脚本之外首先执行】
!#/bin/bash
while true
do
find /var/html/www -type f -mtime 0|xargs md5sum > lx02.log
diff lx01.log lx02.log |grep "^>"|awk ‘{print $3}‘|xargs echo >>/tmp/check.log
mail -s modifile lx@qq.com </tmp/check.log
sleep 180
done
谢迪
[root@mysql xiedi]# cat md5sum.sh
#!/bin/sh
#oldboy linux by xiedi
pass=/server/scripts/xiedi/
path=/var/html/www
n1=`find $path -type f|wc -l`
n2=`cat $pass/old_file.log |wc -l`
while true
do
f=`md5sum -c /server/scripts/xiedi/md5sum.db 2>/dev/null|grep "FAILED"|wc -l`
if [ $f -ne 0 ] || [ $n1 -ne $n2 ]
then
find $path -type f>$pass/new_file.log
diff $pass/new_file.log $pass/old_file.log>/opt/check.log
echo "`md5sum -c /server/scripts/xiedi/md5sum.db 2>/dev/null|grep "FAILED"`">>/opt/check.log
mail -s "md5sum has change `date`" 397731124@qq.com</opt/check.log
fi
sleep 3
done
18.rsync系统启动脚本
企业面试题16:企业案例:写网络服务独立进程模式下rsync的系统启动脚本
例如:/etc/init.d/rsyncd {start|stop|restart} 。
要求:
1.要使用系统函数库技巧。
2.要用函数,不能一坨SHI的方式。
3.可被chkconfig管理。
解答:思路
-
rsync启动命令: rsync --daemon
-
rsync 停止命令: kill -USR2 /var/run/rsyncd.pid
-
加入到chkconfig管理,先把脚本拷贝到/etc/init.d下面,给脚本执行权限,然后通过chkconfig --add rsync添加到管理
我的方法
[root@gw rsync]# vim rsyncd.sh
#!/bin/sh
# chkconfig: 2345 20 80
# description: start rsync and stop rsync scripts.
. /etc/init.d/functions
pidfile=/var/run/rsyncd.pid
start(){
if [ ! -f $pidfile ];then
rsync --daemon &>/dev/null
action "starting rsync...." /bin/true
else
echo "rsync is running"
fi
}
stop(){
if [ ! -f $pidfile ];then
echo "rsync is not running"
else
kill -USR2 `cat $pidfile`
rm -f $pidfile
action "stopping rsync...." /bin/true
fi
}
restart(){
stop
sleep 2
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "USAGE: $0 {start|stop|restart}"
esac
李想
#!/bin/bash
#start the rsync
#chkconfig: 2345 56 24
#description: This is about rysnc restart shell
. /etc/init.d/functions
RETVAL=0
prog="rsync"
#check if rsync is already running
start(){
if [ ! -f /var/run/rsyncd.pid ];then
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
fi
return $RETVAL
}
stop(){
killproc /usr/sbin/rsync
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/run/rsyncd.pid
}
restart(){
stop
start
}
reload(){
restart
}
case "$1" in
start)
action "starting $prog ......" /bin/true
start
;;
stop)
action "stopping $prog ......" /bin/true
stop
;;
restart|reload)
action "stopping $prog ......" /bin/true
stop
action "starting $prog ......" /bin/true
start
;;
*)
echo "Usage:$0 {start|stop|restart}"
exit 1
esac
19.天津抓阄项目
企业面试题17:老男孩教育天津项目学生实践抓阄题目:
好消息,老男孩培训学生外出企业项目实践机会(第6次)来了(本月中旬),但是,名额有限,队员限3人(班长带队)。
因此需要挑选学生,因此需要一个抓阄的程序:
要求:
1、执行脚本后,想去的同学输入英文名字全拼,产生随机数01-99之间的数字,数字越大就去参加项目实践,前面已经抓到的数字,下次不能在出现相同数字。
2、第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出继续等待别的学生输入。
我的方法
while true
do
read -p "please input English name: " a
if [ -z "$a" ];then
continue
else
ran_num=`expr $RANDOM % 10`
zhua_num=`cat /tmp/zhuajiu.log |grep "$ran_num"|awk ‘{print $NF}‘`
if [ -z "$zhua_num" ];then
echo "$a $ran_num"
echo "$a $ran_num" >>/tmp/zhuajiu.log
else
echo "The $zhua_num is used by $a"
sleep 1
continue
fi
fi
done
谢迪(错误,能出现相同的数字)
[root@mysql 19_shell]# cat t17.sh
#!/bin/sh
while true
do
read -p "pls input your english name:" name
if [ -n $name ];then
[ ! -f /opt/a.log ]&&touch /opt/a.log
numb1=`expr $RANDOM % 100`
numb2=`cat /opt/a.log |grep "$numb1"|awk ‘{print $NF}‘`
while [ $numb1 -eq $numb2 ] 2>/dev/null
do
numb1=`expr $RANDOM % 100`
numb2=`cat /opt/a.log|grep $numb1|awk ‘{print $NF}‘`
done
echo "you choose numb is $numb1"
echo "$name $numb1" >>/opt/a.log
fi
done
李想(也错)
seq 1 99 > list
while true
do
read -p "请输入您的姓名:" name
if [ -z "$name" ];then
continue
fi
while true
do
NUM=`expr $RANDOM % 100`
awk ‘/^$NUM$/ {print NR}‘ list &>/dev/null
N=`awk "/^$NUM$/ {print NR}" list`
if [ ! -z "$N" ]
then
echo $N
echo -e "$name\t$NUM" >> result.txt
sed -i ${N}d list
sleep 0.5
else
continue
fi
break
done
done
20.破解MD5sum加密
企业面试题18:老男孩linux企业面试题:
已知下面的字符串是通过RANDOM随机数变量md5sum|cut -c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字?
21029299
00205d1c
a3da1677
1f6d12dd
890684b
解答
我的方法
[root@gw md5]# vim pojie.sh
#!/bin/sh
array=(
21029299
00205d1c
a3da1677
1f6d12dd
890684b
)
for n in {0..32767}
do
num=`echo $n|md5sum|cut -c 1-8`
for i in ${array[*]}
do
if [ "$num" == "$i" ];then
echo "$i $n"
fi
done
done
李想
#!/bin/bash
md5_opt=( 21029299
00205d1c
a3da1677
1f6d12dd
890684b
)
for((i=0;i<999999;i++));do
for md5 in ${md5_opt[*]} ; do
num_md5=`echo $i | md5sum | cut -c 1-8`
if [ $md5 == ${num_md5} ] ; then
echo $i $md5
fi
done
done
[root@gw md5]# sh pojie.sh
00205d1c 1346
1f6d12dd 7041
a3da1677 25345
21029299 25667
21.检查网站地址是否正常
企业面试题19:批量检查多个网站地址是否正常
要求:shell数组方法实现,检测策略尽量模拟用户访问思路
http://www.etiantian.org
http://www.taobao.com
http://oldboy.blog.51cto.com
http://10.0.0.7
curl -I -s -w "%{http_code}\n" www.baidu.com -o /dev/null
我的方法
#!/bin/sh
. /etc/init.d/functions
url=(
http://www.etiantian.org
http://www.taobao.com
http://oldboy.blog.51cto.com
http://10.0.0.7
)
main(){
for i in ${url[*]}
do
curl_num=`curl -I -s -w "%{http_code}\n" -o /dev/null $i`
#curl_num=`curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}" $i`
if [ "$curl_num" == "200" -o "$curl_num" == "301" ]
then
action "$i" /bin/true
else
action "$i" /bin/false
fi
done
}
main
李想
#!/bin/sh
. /etc/init.d/functions
url_list=(
http://10.0.0.5
http://www.baidu.com
http://oldboy.blog.51cto.com
http://10.0.0.19
)
check_url(){
[ $# -ne 1 ] && exit 1
curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}" $1
}
main(){
for ((i=0;i<${#url_list[*]};i++))
do
code=`check_url ${url_list[i]}`
if [ "$code" != "200" -a "$code" != "301" ];then
action "${url_list[i]}" /bin/false
else
action "${url_list[i]}" /bin/true
fi
done
}
main
22.按字母,单词出现频率排序
企业面试题20(中企动力)::用shell处理以下内容
1、按单词出现频率降序排序!
2、按字母出现频率降序排序!
the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support sections for more infomation
按单词
法1
[root@gw tr]# cat a.log |tr " ,." "\n"|egrep -v "^$"|sort |uniq -c|sort -nr
2 support
2 squid
2 and
1 users
1 toassist
1 the
1 sections
1 resources
1 provides
1 project
1 Please
1 of
1 number
1 more
1 installations
1 infomation
1 implement
1 for
1 documentation
1 design
1 browsethe
1 a
法2(李想)
[root@lixiang scripts]# tr ‘{ |,|.}‘ ‘\n‘<1.txt|grep -v ‘^$‘|awk ‘{S[$1]++}END{for(i in S) printf "%-20s %-10s\n", i,S[i]}‘|sort -nrk 2
support 2
squid 2
and 2
users 1
toassist 1
the 1
sections 1
resources 1
provides 1
project 1
Please 1
of 1
number 1
more 1
installations 1
infomation 1
implement 1
for 1
documentation 1
design 1
browsethe 1
a 1
按字母:
方法1
tr "{ |,|.}" "\n" <a.log|grep -v "^$"|awk -F "" ‘{for (i=1;i<=NF;i++) print $i}‘|sort|uniq -c|sort -nr
19 s
17 e
16 o
14 t
方法2
cat a.log|tr ‘ ‘ ‘\n‘|grep -o ‘\w‘|sort|uniq -c|sort -nrk1
19 s
17 e
16 o
14 t
12 n
12 i
11 r
方法3
tr "{ |,|.}" "\n" <a.log |awk -F "" ‘{for(i=1;i<=NF;i++)array[$i]++}END{for(key in array)print array[key],key}‘|sort -rn
19 s
17 e
16 o
方法4
tr "{ |,|.}" "\n" <a.log |awk -F "" ‘{for(i=1;i<=NF;i++)array[$i]++}END{for(key in array)print array[key],key|"sort -rn"}‘
19 s
17 e
16 o
14 t
13 i
[root@mysql oldboy]# cat word.txt
abcde,fghg
[root@mysql oldboy]# cat word.txt |grep -o "\w"
a
b
c
d
e
f
g
h
g
[root@mysql oldboy]# cat word.txt |grep -o "[a-z]"
a
b
c
d
e
f
g
h
g
[root@mysql oldboy]# cat word.txt |grep -o "[0-9a-zA-Z_]"
a
b
c
d
e
f
g
h
g
grep :
-o : --only-matching
Show only the part of a matching line that matches PATTERN.
\w : 等同与[0-9a-zA-Z_]
他可以把一条语句,分开为单个单词!!
echo $str|awk ‘BEGIN{FS=""}{for(i=1;i<=NF;i++)if($i !~ /[., ]/)count[$i]++}END{for(key in count)print key,count[key]}‘
cp拷贝隐藏文件需要加.*
shell颜色
前景色
echo -e "\033[30m 黑色字oldboy trainning \033[0m"
echo -e "\033[31m 红色字oldboy trainning \033[0m"
echo -e "\033[32m 绿色字oldboy trainning \033[0m"
echo -e "\033[33m 黄色字oldboy trainning \033[0m"
echo -e "\033[34m 蓝色字oldboy trainning \033[0m"
echo -e "\033[35m 紫色字oldboy trainning \033[0m"
echo -e "\033[36m 天蓝字oldboy trainning \033[0m"
echo -e "\033[37m 白色字oldboy trainning \033[0m"
RED_COLOR=‘\E[1;31m‘
GREEN_COLOR=‘\E[1;32m‘
YELLOW_COLOR=‘\E[1;33m‘
BLUE_COLOR=‘\E[1;34m‘
RES=‘\E[0m‘
man手册查看颜色man console_codes
背景色
echo -e "\033[40;37m 黑底白字 welcome to old1boy\033[0m"
echo -e "\033[41;37m 红底白字 welcome to old2boy\033[0m"
echo -e "\033[42;37m 绿底白字 welcome to old3boy\033[0m"
echo -e "\033[43;37m 黄底白字 welcome to old4boy\033[0m"
echo -e "\033[44;37m 蓝底白字 welcome to old5boy\033[0m"
echo -e "\033[45;37m 紫底白字 welcome to old6boy\033[0m"
echo -e "\033[46;37m 天蓝白字 welcome to old7boy\033[0m"
echo -e "\033[47;30m 白底黑字 welcome to old8boy\033[0m"
字背景颜色范围:40----49
40:黑
41:深红
42:绿
43:黄色
44:蓝色
45:紫色
46:深绿
47:白色
字颜色:30-----------39
30:黑
31:红
32:绿
33:黄
34:蓝色
35:紫色
36:深绿
37:白色
===============================================ANSI控制码的说明
\33[0m 关闭所有属性
\33[1m 设置高亮度
\33[4m 下划线
\33[5m 闪烁
\33[7m 反显
\33[8m 消隐
\33[30m -- \33[37m 设置前景色
\33[40m -- \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标