现在的服务器一般都是 linux 或unix操作系统,难免会接触到一些shell,那么shell脚本是什么呢? shell脚本是一组代码的组合。
这是基础代码:
http://www.xiaosongit.com/index/detail/id/75.html
shell中正则的使用方法
https://www.jb51.net/tools/shell_regex.html
shell脚本定义方法
# 通过脚本来传递,这里$0指脚本名,$1为第一个参数,$2为第二个参数 [root@host ~]# ./script.sh 1 2 Total = 3 [root@host ~]# vim script.sh #!/bin/bash function add() { total=$(expr $1 + $2) echo -e "Total = $total" } add $1 $2
一条命令让你明白shell中read脚本命令
[root@host ~]# ./script.sh Enter Password: The password your input is: Test@1234\ [root@host ~]# vim script.sh #!/bin/bash read -n10 -t30 -r -s -d $ -p "Enter Password:" password echo -e "\nThe password your input is:$password"
-p 提示语句,后面接输入提示信息,这里为'Enter Password: '
-n 参数个数,有时候要限制密码长度,或者其他输入长度限制,比如[Y/N],只输入输入一位,-n1
-s 屏蔽回显,屏幕上不显示输入内容,一般用于密码输入
-t 等待时间,这里设置30秒,30秒内未输入或者输入不全,终止
-d 输入界限,这里是$,输入到$,自然终止输入
-r 屏蔽特殊字符\的转译功能,加了之后作为普通字符处理
现在看看如何编写脚本
nginx.sh
#!/bin/bash #nginx.sh #chkconfig:2345 90 20 #description : my server daemon case $1 in start) echo "nginx start" ;; stop) echo "nginx stop" ;; restart) echo "nginx restart" ;; *) echo "please input start|stop|restart" ;; esac
给这个脚本加上执行的权限: chmod a+x nginx.sh
上面是最基本的命令格式,有什么信息直接往里面套即可。
chkconfig myserver on
[root@localhost logs]# chkconfig --list | grep mysql
mysqld 0:off1:off2:on3:on4:on5:on6:off
通过 chkconfig --list | grep myserver
我们会把写好的脚本放在 /etc/init.d/ 这个目录下
第二种方法:
也可以不写脚本,直接指定开机启动
vim /etc/rc.local
然后 通过 ./nginx.sh start 试试看
./nginx.sh stop
nginx start
./nginx.sh restart
nginx restart
./nginx.sh asdfasdfasdf
please input start|stop|restart
这样的话,一个简单的脚本就编写好了,但是没有植入业务代码。
打印方法中的格式
定义一个打印方法 并调用
echo -e "\033[$color;40m $info \033[0m"
color:
30 黑
31 红
32 绿
33 黄
34 蓝
35 紫
36 浅蓝
#!/bin/bash #a.sh function print(){ info=$1 color=31 if [ $# -gt 1 ];then color=$2 fi echo -e "\033[$color;40m $info \033[0m" } print abcde 34
监控内存使用情况:
#!/bin/bash #mem.sh free=`free -m |awk '{if(NR==2){print $4}}'` use=`free -m |awk '{if(NR==2){print $3}}'` total=`free -m |awk '{if(NR==2){print $2}}'` echo $total echo -e "\033[32;40m[0k]\033[0m" ~ ~
sed 获取行
可以参考使用文档
sed 's/^/添加的头部&/g' //在所有行首添加
sed
's/$/&添加的尾部/g' //在所有行末添加
sed '2s/原字符串/替换字符串/g' //替换第2行
sed
'$s/原字符串/替换字符串/g' //替换最后一行
sed '2,5s/原字符串/替换字符串/g' //替换2到5行
sed
'2,$s/原字符串/替换字符串/g' //替换2到最后一行
awk 获取列
awk '{print $1}'
awk '{if(NR==3){print $1}}' 使用了if语句 NR==3 打印 $1 元素
nl file 以文件行号的形式显示文件内容
if 语句写法
if [ ds -lt 45 ];then fi if [ ds -lt 45 ];then echo 45 else echo 66 fi
#判断 /a 是不是目录 if [ -d "/a" ];then echo "目录" else echo "不是目录" fi
for循环: for循环中必须两个括号
for((i=0;i<10;i++)) do echo $i done #第二种风格 for i in {1..100} do echo $i done
#!/bin/bash #Version 1.0.0 #Time 2015年02月05日 14:24:15 #FileName apachexsite.sh httpd_Vsersion=2.4.12 DomainName= #解析域名和绑定域名 DomainName=$1 mkdir -p /a/domains/${DomainName}/public_html chown -R www:www /a/domains/${DomainName}/public_html log_path=\"/a/domains/${DomainName}/public_html/${DomainName}/ errorlog=${log_path}${DomainName}-errorlog.log\" customlog=${log_path}${DomainName}.log\" #写入配置文件 cat > /a/apps/httpd-${httpd_Vsersion}/conf/vhosts/${DomainName}.conf <<EOF <VirtualHost *:80> ServerName $1 DocumentRoot /a/domains/${DomainName}/public_html ErrorLog ${errorlog} CustomLog ${customlog} common </VirtualHost> EOF echo ${DomainName}" vhost create success , website directory : /a/domains/"${DomainName}"/public_html/" service httpd restart exit 1
mysql安装脚本:
#!/bin/bash #mysql_install.sh #判断 如果此目录发现 install.lock 就不能执行了 #定义一个打印方法 function print(){ info=$1 color=31 if [ $# -gt 1 ];then color=$2 fi echo -e "\033[$color;40m $info \033[0m" } #目录主目录 basepath=$(cd `dirname $0`; pwd) #lock file lock_file="${basepath}/install.lock" if [ -f "$lock_file" ]; then print "mysql server is installted if your reinstall please delete ./install.lock" exit fi mysqltar="mysql-5.6.35.tar.gz" cmaketar="cmake-2.8.12.tar.gz" #判断两个文件是否存在,如果不存在直接退出 if [ ! -f $mysqltar ]; then print "install tar not exists:\n ${mysqltar} \n ${cmaketar}" exit fi if [ ! -f $cmaketar ]; then print "install tar not exists:\n ${mysqltar} \n ${cmaketar}" exit fi #安装需要的文件包 yum -y install gcc pcre gcc-c++ pcre-devel autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers bison #cake cake="${basepath}/cmake-2.8.12.tar.gz" #解压文件 tar -xf $cake #切换到cmake-2.8.12 这个目录 cd "${basepath}/cmake-2.8.12" print "cmake-2.8.12 start install ..." 34 ./configure make&make install print "cmake-2.8.12 install success [ok]" 32 #切换到主目录 src cd "${basepath}" mysql_path="/usr/local/mysql5.6" groupadd mysql useradd -g mysql -s /bin/false mysql mkdir -p $mysql_path chown -R mysql:mysql $mysqlpath mkdir -p $mysql_path/data chown -R mysql:mysql $mysql_path/data #mysql 包 mysql="${basepath}/mysql-5.6.35.tar.gz" echo "mysql-5.6.35 start install ..." echo "tar xf mysql-5.6.35..." tar -xf $mysql #cd 解压目录 cd "${basepath}/mysql-5.6.35" cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql5.6 -DMYSQL_DATADIR=/usr/local/mysql5.6/data -DSYSCONFDIR=/etc #进行安装 make && make install print "mysql-5.6.35 install success [ok]" 32 #复制配置文件到 /etc/目录下 rm -rf /etc/my.cnf cp ./support-files/my-default.cnf /etc/my.cnf #替换配置文件 只负责18行 和 19行的数据替换 sed -i "18s/# basedir = ...../basedir=\/usr\/local\/mysql5.6/g" /etc/my.cnf sed -i "19s/# datadir = ...../datadir=\/usr\/local\/mysql5.6\/data/g" /etc/my.cnf #进入到安装目录,然后执行脚本 cd $mysql_path ./scripts/mysql_install_db --user=mysql echo "mysql_db init success [ok]" #复制变量 可以使用service进行管理 cp ./support-files/mysql.server /etc/rc.d/init.d/mysqld chmod 755 /etc/rc.d/init.d/mysqld chkconfig mysqld on #负责替换数据 sed -i "46s/basedir=/basedir=\/usr\/local\/mysql5.6/g" /etc/rc.d/init.d/mysqld sed -i "47s/datadir=/datadir=\/usr\/local\/mysql5.6\/data/g" /etc/rc.d/init.d/mysqld #启动mysql数据库 service mysqld start print "mysql server is running ..." 32 sleep 2 #在 54行下 引入mysql变量 引入环境变量 sed -i '54a\export PATH=$PATH:\/usr\/local\/mysql5.6\/bin' /etc/profile source /etc/profile #初始化密码 echo "init password" echo -n "please input your mysql password for root: " read pass /usr/local/mysql5.6/bin/mysqladmin -u root password $pass print "mysql success ok...." 32 print "Please must reexecute the command: source /etc/profile \n after login mysql server mysql -uroot -p " 32 #返回到这个目录 cd "${basepath}" #建立一个文件锁 touch "install.lock"
grep 去掉 grep进程id
当我们使用 ps -ef | grep 'nginx' 的时候,获取到的进程中会包含 grep 的进程号
这个是我们不需要的,需要去掉,那么应该怎么去?
看下面的命令: grep -v 'grep' 过滤掉 grep
[root@localhost song]# ps -ef | grep 'nginx' root 2426 1 0 Nov28 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 2429 2426 0 Nov28 ? 00:00:03 nginx: worker process nginx 3723 2042 0 Nov28 ? 00:08:47 php-fpm: pool www nginx 13563 2042 1 15:09 ? 00:04:25 php-fpm: pool www nginx 13570 2042 1 15:10 ? 00:04:19 php-fpm: pool www root 16611 3615 0 19:01 pts/3 00:00:00 grep nginx
[root@localhost song]# ps -ef | grep 'nginx' | grep -v 'grep' root 2426 1 0 Nov28 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 2429 2426 0 Nov28 ? 00:00:03 nginx: worker process nginx 3723 2042 0 Nov28 ? 00:08:47 php-fpm: pool www nginx 13563 2042 1 15:09 ? 00:04:25 php-fpm: pool www nginx 13570 2042 1 15:10 ? 00:04:19 php-fpm: pool www
我们通过了 grep -v 'grep' 过滤了 grep 命令
下一步通过 awk 获取到进程的pid
[root@localhost song]# ps -ef | grep 'nginx' | grep -v 'grep' | awk '{print $2}' 2426 2429 3723 13563 13570 shell脚本
#!/bin/sh # shell脚本进阶教程 # 1.常用知识点:变量设置/日期设置/格式化输出/定义函数/函数传参/脚步传参/变量的嵌套和迭代 # 2.常用环境:/数据库监控/本地日志监控/批量处理/定期获取表数据/备份 # 3.常用循环:for/while # 4.常用命令:sed/cut/awk/ # 5.crontab 计划任务 # 第一部分:常用知识点 # 1.【变量设置及变量替换】 # 1.1 全局变量和局部变量-在脚本中的位置来区分 # 全局变量: 脚本中直接定义 # 局部变量: 在循环语句中/自定义函数中 # 从位置顺序上来说: # 全局变量:一般在脚本的开头位置,先设置好;或者是在函数定义/循环语句之前先定义。 # 局部变量:用于局部的调用,比如循环语句中/自定义函数里;循环或函数之外调用是不生效的 # 1.2 恒定变量和动态变量-变量的值是否变化 # 格式: # 恒定变量:eg: xxx='' 或者 xxx=" " 或者 或者 xxx=120 (数字或者端口的定义不用引号) 或者 xxx=" '' " 错误格式:相同引号不能套用xxx="""" # 动态变量:eg: xxx=`` 反引号:键盘上数字1 左边的键 # 动态变量,两种常用设置: # xxx=`shell命令` :直接把shell命令的结果赋值给xxx (xxx=`cat /data/a.txt|grep '3306'` 将含有3306的行直接赋值给xxx变量) # xxx=`$cmd` : cmd="hello world" (将cmd变量的内容赋值给xxx,cmd可以是恒定变量也可以是动态变量) # 单引号和双引号和多个引号的区别: # 单引号:是完全引用:举两个例子: # 1. \n :回车的意思 \t:是tab空格的意思 定义:str1='hello world!\nhello world!' 输出结果: hello world!\nhello world! 原样输出 # 2.定义SQL语句:sql1='select * from db1.tb1 where name="joho" and time>"$start_time"' 由于是原样输出 start_time变量不会成功替换 # 双引号:输出字面值 但是特殊字符除外:比如转义字符:\t \r \n 变量替换:$ # 1.定义:str2="hello world!\nhello world!" 输出两行 # 2.sql2="select * from db1.tb1 where name='joho' and time>'$start_time'" 正确! 时间必须引号引起来。 # 多个引号(单引号或双引号):使用环境:定义的变量里面有:单引号,双引号,变量替换以及反引号 # 我使用过的唯一的例子:批量建表时: # seg01:批量打印建表语句00~99,不是很常用 for i in seq `0 99` do num=`printf "%02d" $i` #格式化0~9 变成:00~09 (两位数字) sql="""create table `BLDB`.`log_message_'''$num'''`( `id` int, `name` varchar(10), primary key(id) )engine=innodb; """ # 之所以引用3个双引号是因为 :SQLyog工具导出的语句的 库名,表名,字段名 都用反引号引着。 # 3个引号里面的变量替换,必须用3个单引号引,才能生效。 # 手动把反引号去掉 可以不用3个双引号的。 done # 变量例子: user='admin' paswd='pssword' host='172.2.1.1' port=3306 dir1='/data/scripts' file1="${dir1}/log.txt" # 常用的变量替换 DateMark=`date '+%Y-%m-%d %H:%M:%S'` # 动态变量设置当前的时间变量:2017-08-06 22:09:00 # 2.【日期/时间设置】 # 带日期的表名/表中时间字段/脚本中的时间标志 # 时间日期的分类:当前时间/n分钟之前/n小时之前/n分钟之内/ # 时间的格式化:%Y:年 %m:月 %d:天 %H:小时 %M:分钟 %S:秒 # 2.1 当前时间: NowTime=`date '+%Y-%m-%d %H:%M:%S'` #2017-08-06 22:09:00 NowTime=`date '+%Y%m%d %H%M%S'` #20170806 220900 # 2.2 n分钟之前: n minute ago /n day ago BeforeTime=`date -d'2 minute ago' '+%Y-%m-%d %H:%M:%S'` # 2.3 时间范围:最近5分钟 # 无论什么环境,当前时间不计算,因为当前一分钟是不完整的 # 用于sql查询条件中时间字段的限制:格式的样式要与表中格式一致 StartTime=`date -d'1 minute ago' '+%Y-%m-%d %H:%M:%S'` EndTime=`date -d'5 minute ago' '+%Y-%m-%d %H:%M:%S'` # 2.4 表名:BLDB.LOG_MESSAGE_20170806 # TB_MARK=`date '+%Y%m%d'` # 20170806 TB_NAME="BLDB.LOG_MESSAGE_`date '+%Y%m%d'`" # 1.直接写入 : 不建议使用 TB_NAME="BLDB.LOG_MESSAGE_${TB_MARK}" # 2.变量替换 :最常用:易于随时修改 # 2.5 脚步中的时间标志 # echo "[${NowTime}] : Succeeded!" #执行命令后 打印输出结果 # 3.【格式化输出】: # 好处: # 1.输出的规范要求,比如:00~09 而不是0~9;浮点型位数要求:一般用于建100张表 # 2.左右对齐:输出美观要求,行列对齐 便于查看结果 # 常用的3中:数值/字符/浮点数 # 数值 #seg02: for i in `seq 0 9` do printf "%02d" "$i" # 输出2位,不够用0补齐,格式化后直接打印输出 done # 字符串 printf "%10s %s" "hello!" "it's a dog!" # 输出两个字段,第一个字段占10个字符,默认右对齐,不够左侧空格补齐 printf "%-10s %s" "hello!" "it's a dog!" # -:左对齐,右侧空格 # 浮点数 num=98.2245 printf "%2.2f" "$num" # 格式化:小数点左侧2位,右侧保留2位。 用于成功率/百分比 # 4. 【定义函数】 # 4.1 常规函数(无传参) #定义格式: GET_INFO() { NAME='Jhon' echo "My name is ${NAME}" } # 函数调用方式:直接调用函数名 # 直接脚本中写函数名 GET_INFO #seg03 :完整脚本 vim getinfo.sh #-------------------------------(虚线是无用的) #!/bin/sh #shell脚本的开头设置 # def:function GET_INFO() { NAME='Jhon' echo "My name is ${NAME}" } # excute: function GET_INFO #------------------------------- # 执行脚本及输出内容 ./getinfo.sh My name is jhon # 4.2 定义传参函数: # 定义格式:带有2个参数的函数 # FUNCTION: GET_INFO() { PORT=$1 IP=$2 echo "MYSQL PORT IS : ${PORT} AND MySQL HOST IS ${IP}" result=`mysql -uadmin -p'password' -h${IP} -P${PORT} -NBe"SELECT * FROM URCS_BLDB.LOG_MESSAGE_01;"` # 读取表数据,将输出结果赋值给result变量 echo "$result" >> /data/log.txt #将结果写入指定文件 } # 调用方式:函数名 参数1 参数2 GET_INFO 3306 '172.21.1.1' GET_INFO 3307 '172.21.1.2' # 以上是两次调用函数。适用于相似的结果输出,不同的传入变量 # 通常函数传参 和脚本传参 相结合 做监控项时 非常给力。现网监控就是如此做的 # 5. 【脚本传参】 # 环境:使用一个脚本,处理相似的操作类。比如:不同MySQL用端口来区分,每个MySQL监控项是一样的。唯一不同的是端口,因此端口就可以作为变量,作为脚本的参数 # 脚本调用方式:1个脚本参数 ./getinfo.sh 3306 # 脚本中的所有输出内容都是3306数据库相关的 ./getinfo.sh 3307 # 脚本中的所有输出内容都是3307数据库相关的 # 脚本参数在脚本中的体现 # 脚本开头位置,设置脚本参数变量 db_port=$1 # $1 代表脚本后面的第一个参数;$2 代表脚本后面跟的第二个参数;$0 代表脚本本身 # 这种变量赋值,是将 脚本参数原样的赋值给:db_port。脚本中就可以直接引用db_port 这个变量来代表端口。 # 如果是字符串作为脚本参数,字符串里有特殊符号或者空格,需要用单引号 引起来。 #seg04: 脚本通过传入端口,来监控该数据库实例的 某个监控项 #!/bin/sh db_port=$1 db_item=$2 # 代表监控项:比如 连接数,主从状态。。。。;可以看做是一个触发动作,后面会讲,总之这个是变化的量 echo "$db_port : $db_item" # 执行方式:./getinfo.sh 3306 conn # 输出结果:3306 :conn # 6. 【脚本变量的嵌套】 # 6.1 常规的 嵌套 # seg05: #!/bin/sh # SQL查询的where条件 S1='timeout' S2='error code' ...... # 定义函数:根据传入的条件生成SQL语句;将语句赋值给一个变量,并将变量传入另一个SQL查询函数中,将查询结果返回或者写入文件 CREATE_SQL() { S=$1 SQL='''SELECT * FROM URCS_BLDB.LOG_MESSAGE_01 WHERE message like "%'''$S'''%" ;''' # 关于引号的使用,目的是生成的SQL是正常就行。 echo $SQL } # 定义SQL查询函数 GET_INFO() { sql=$1 mysql -uadmin -p'pasd' -h172.21.1.1 -P3306 -NBe"$sql"; } SQL1=`CREATE_SQL "$S1"` # 通过函数生成SQL语句,赋值给变量SQL1 SQL1_DATA=`GET_INFO "$SQL1"` #传入SQL1,函数产生查询结果,并赋值给SQL1_DATA变量。 echo $SQL1_DATA >SQL1.txt # 将变量内容写入文件中 # 第二部分 # 常用环境 # 1. 【数据库性能参数监控】 # 监控脚本思路: # (1).监控项很多,避免每次都访问数据库,因此,通过:show global status\G 将结果写入一个文件 # (2).每个监控项,定义一个函数,从文件读取信息,经过处理返回 # (3).通过脚本传参的方式 触发函数并返回值 ./xxx.sh action # (4).多实例情况,通过端口来区分,复用脚本。通过脚本传参来实现:./xxx.sh port action # (5).有n个监控项,一分钟会触发脚本n次。 只需在第一次触发时,就生成文件。因此需要定义函数,将status信息写入文件,并检查,文件是否存在,存在跳过,不存在,读取信息并写入。 # (6).生成文件以时间标志,因此需要清理机制。定义一个清理函数作为监控项,在zabbix中每隔30分钟调用一次。 # 简写脚本:主从状态的监控 # seg06: #!/bin/sh #. /etc/profile #. /etc/bashrc # name : slave.sh ############# # 定义MySQL命令 变量: MYSQL_BIN="/usr/local/mysql5715/bin/mysql -umonitor -pmonitor" # 定义生成文件的时间标志 INFO_TIME=`date +%m%d%H%M` # 定义输出文件目录 INFO_DIR="/usr/local/zabbix/scripts/tmp/" # 定义MySQL的端口 MYSQL_PORT="$1" # 定义生成的文件名 INFO_FILE="/usr/local/zabbix/scripts/tmp/SLAVE_INFO_${MYSQL_PORT}_${INFO_TIME}" ############# # 定义函数,判断文件是否存在,不存在,获取slave信息,并写入文件;存在就跳过 GET_INFO(){ if [[ -f ${INFO_FILE} ]] ; then break else ${MYSQL_BIN} -S /data/socket/mysql${MYSQL_PORT}.sock -e 'SHOW SLAVE STATUS \G' >${INFO_FILE} fi } # 定义从库延时函数 Seconds_Behind_Master(){ SBM=`/bin/egrep -w 'Seconds_Behind_Master' ${INFO_FILE} | awk '{print $2}' ` echo ${SBM} } # 定义SQL线程状态 Slave_SQL_Running(){ THD_SQL=`/bin/egrep -w 'Slave_SQL_Running' ${INFO_FILE} | awk '{print $2}' ` if [[ ${THD_SQL} = 'No' ]] ; then echo 0 else echo 1 fi } # 定义IO线程状态 Slave_IO_Running(){ THD_IO=`/bin/egrep -w 'Slave_IO_Running' ${INFO_FILE} | awk '{print $2}' ` if [[ ${THD_IO} = 'No' ]] ; then echo 0 else echo 1 fi } # 定义函数 判断是主还是从 R_EMLP(){ RMLP=`/bin/egrep -w 'Read_Master_Log_Pos' ${INFO_FILE} | awk '{print $2}' ` EMLP=`/bin/egrep -w 'Exec_Master_Log_Pos' ${INFO_FILE} | awk '{print $2}' ` R_EMLP=$[${RMLP}-${EMLP}] echo ${R_EMLP} } ####################### GET_INFO # 每次执行脚本都触发:获取信息的函数 # 下面两个变量 如果=4,说明是主库,返回值:3,zabbix判断认为是主,不会触发报警 RMLP=`/bin/egrep -w 'Read_Master_Log_Pos' ${INFO_FILE} | awk '{print $2}' ` RELP=`/bin/egrep -w 'Relay_Log_Pos' ${INFO_FILE} | awk '{print $2}' ` # 下面的:case $2 in ,通过判断脚本传的第二个参数,是哪个,就触发对应的函数,并返回对应的值 if [[ ${RMLP} == 4 ]] && [[ ${RELP} == 4 ]] ; then case $2 in sla_sbm) echo 3 ;; thd_sql) echo 3 ;; thd_io) echo 3 ;; sla_rem) echo 3 ;; *) esac else case $2 in sla_sbm) Seconds_Behind_Master ;; thd_sql) Slave_SQL_Running ;; thd_io) Slave_IO_Running ;; sla_rem) R_EMLP ;; *) esac fi # 定义清理函数 # 定义清理函数:每隔30分钟清理一次,每次把前一分钟之前的都清理掉 GLO_CLEAR(){ /bin/find ${INFO_DIR}/*_INFO_* -ctime -1 | xargs rm -f FILE_NUM=`/bin/find ${INFO_DIR} -name "*_INFO_*" -ctime -1 | wc -l` if [[ ${FILE_NUM} == 0 ]] ; then echo 1 else echo 0 fi } #测试:./slave.sh 3306 thd_sql 会得到一个返回值 # 2.【本地log日志,关键字查询】 # SQL查询本地数据库表,含有错误关键字的行总数, # 脚本思路 # (1).错误关键字 查询多,以标准格式,放到单独的文件里。脚本通过循环读取该文件,进行SQL生成 # (2).SQL 查询的结果,存放到对应的文件 # (3).输出信息中字段条件多,所以通过其它脚本处理该信息 # (4). # 简写脚本 #!/bin/sh # 定义变量 HOST="localhost" PORT=9306 USER="root" PSWD="root" DB_NAME="LogDB" TB_NAME="LOG_"`date +'%Y%m%d'` MYSQL_CMD="/home/mysql/Percona-Server/bin/mysql -u${USER} -p${PSWD} -h${HOST} -P${PORT} -S /tmp/mysql.sock" # 时间变量设置,取值范围前一分钟的数据 TIME0=`date +'%Y-%m-%d %H:%M'` # 当前时间 TIME1=`date -d "1 minutes ago" +'%Y-%m-%d %H:%M'` # 前一分钟:2017-08-05 10:34 秒钟在SQL定义时添加 # 定义结果的输出文件的目录: # tmp_dir FILE_DIR="/data/scripts/shelldir" # 定义错误关键字的格式 文件 KeyFile='/data/scripts/KeyFile.txt' 内容: ####too many connections####connect.txt#### ####timeout####timeout.txt#### #定义SQL生成函数:参数:关键字 GET_SQL() { Key=$1 SQL='''SELECT A.ServiceName,IFNULL(B.count_error,0) AS count_total FROM (select distinct(ServiceName) from '''${DB_NAME}.${TB_NAME}''' where (Time >="'''${TIME1}':00''''" AND Time<="'''${TIME0}':59''''")) AS A left join (select ServiceName,count(*) AS count_error from '''${DB_NAME}.${TB_MARK}''' WHERE (Time >="'''${TIME1}':00''''" AND Time <="'''${TIME1}':59''''") AND (Message LIKE "%'''${Key}'''%" OR Error LIKE "%'''${Key}'''%") group by ServiceName) AS B ON A.ServiceName=B.ServiceName group by A.ServiceName;''' echo $SQL } # 定义SQL查询函数:参数:SQL语句,文件名 GET_INFO() { SQL=$1 FILE=$2 ${MYSQL_CMD} -NBe "${SQL}" >>${FILE_DIR}/${FILE} } # 循环读取关键字文件,一次进行SQL生成,SQL查询 # 主程序 cat ${KeyFile}| while read line do # 截取关键字和输出文件名字 Key=`echo ${line}|awk -F'####' '{print $1}'` Outfile=`echo ${line}|awk -F'####' '{print $2}'` # 生成SQL语句 SQL=`GET_SQL "$Key"` # 查询结果写入文件 GET_INFO "$SQL" "$Outfile" done # 3.【批量处理】 # 常用 for i in `seq 0 99` do echo "truncate table xxxx_$i" done #命令行:for i in `seq 1 100`;do echo "truncate table xxxx_$i;";done # 4种批量建表程序 ##create 100 tables #!/bin/sh # db_name='USE RenmaiInfluenceDB' for i in {0 99}; do len=`expr length $i` if [ $len -eq 2 ];then num=$i else num="0${i}" fi echo ''' CREATE TABLE `logRegister_'''$num'''` ( `Id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增id', `AwardId` int(10) NOT NULL COMMENT '奖品Id', `UserId` int(10) NOT NULL COMMENT '中奖用户', `CourierName` varchar(20) DEFAULT NULL COMMENT '快递名', `CourierNumber` varchar(40) DEFAULT NULL COMMENT '运单号', `CreateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '中奖时间', PRIMARY KEY (`Id`), KEY `IX_SignLotteryWinner_UserId_CreateDate` (`UserId`,`CreateDate`) ) ENGINE=InnoDB AUTO_INCREMENT=1602 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='打卡中奖表'; ''' echo done ======================================================================================================== #!/bin/sh #creat tables for i in `seq 1 15` do var=`printf "%02d\n" $i` echo ''' CREATE TABLE `logRegister_'''$var'''` ( `Id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增id', `AwardId` int(10) NOT NULL COMMENT '奖品Id', `UserId` int(10) NOT NULL COMMENT '中奖用户', `CourierName` varchar(20) DEFAULT NULL COMMENT '快递名', `CourierNumber` varchar(40) DEFAULT NULL COMMENT '运单号', `CreateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '中奖时间', PRIMARY KEY (`Id`), KEY `IX_SignLotteryWinner_UserId_CreateDate` (`UserId`,`CreateDate`) ) ENGINE=InnoDB AUTO_INCREMENT=1602 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='打卡中奖表'; ''' echo done ============================================================================ #!/bin/sh # 需要将 SQL 中的" ` " 符号删除 for i in `seq 0 1 99` do STEP=`printf %02d ${i}` create_tab_sql=" CREATE TABLE logRegister_${STEP} ( Id int(11) NOT NULL AUTO_INCREMENT COMMENT '表id', UserId int(11) NOT NULL COMMENT '用户id', UserName varchar(32) COLLATE utf8_unicode_ci NOT NULL COMMENT '用户名', LotteryNumber tinyint(1) NOT NULL COMMENT '今日剩余可抽奖次数', StateTime date NOT NULL COMMENT '当前日期', lottery tinyint(1) NOT NULL DEFAULT '0', award_times tinyint(1) NOT NULL DEFAULT '0', FeitionID int(11) DEFAULT NULL COMMENT '用户飞信号码', PRIMARY KEY (Id), KEY idx (UserId) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='每日用户可游戏次数纪录表';" echo -e ${create_tab_sql} echo done =================================================================================== #!/usr/bin/python import string for i in range(7,13): sql = "CREATE TABLE `UgcFeedContent_2015%02d` LIKE `UgcFeedContent_201503`;" % i print(sql) for i in range(1,13): sql = "CREATE TABLE `UgcFeedContent_2016%02d` LIKE `UgcFeedContent_201503`;" % i print(sql) ======================================== 其余几部分 单独写