Shell

Shell

运维如何写出不耍流氓的Shell脚本

开源技术小白菜 发表了文章 • 2 个评论 • 160 次浏览 • 2016-12-02 22:33 • 来自相关话题

声明

大家都是文明人,尤其是做运维的,那叫一个斯文啊。怎么能耍流氓呢?赶紧看看,编写 SHELL 脚本如何能够不耍流氓。

Mysql备份脚本案例

1、不记录日志的 SHELL 脚本就是耍流氓!
我们经常在工作中会遇到一个苦恼的事情,一个 Shell 脚本到底干了什么,什么时候开始执行,什么时候结束的。尤其是数据库备份,我们想知道我们的 MySQL 数据库备份时间。所以给脚本加日志显得尤为重要。那么我们的脚本应该有一个日志的函数,专门用于记录日志:#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

shell_log "shell beginning, Write log test"
shell_log "shell success, Write log test"


上面的脚本我编写了一个日志函数shell_log,每次记录日志,我们直接执行shell_log把日志内容当作第一个参数传给它就可以了,赶紧试试。[root@LinuxNode2 shell]# cat shell_template.sh.log
2016-08-27 06-01-19 : shell_template.sh :shell beginning ,write log test
2016-08-27 06-01-19 : shell_template.sh :shell success ,write log test
2、直接就能执行的Shell脚本很容易耍流氓?
一个脚本直接就能执行?难道不是直接就能执行吗?试想,你临时编写了一个特别重要的脚本,干的事情可能有破坏性,一不小心被别人./执行了怎么办呢?而且很多时候我们一个脚本的功能可能有多个,所以我们有必要让用户可以选择进行执行。#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log 
shell_log(){
    LOG_INFO=$1
    echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
    echo $"Usage: $0 {backup}"
}


# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
    shell_log "mysql backup start"
    shell_log "mysql backup stop"
}

# Main Function
main(){
    case $1 in
        backup)
            mysql_backup
            ;;
        *)
            shell_usage;
    esac
}

#Exec
main $1


上面的脚本我们编写了shell_usage函数,用来告诉用户,这个脚本的使用方法。同时,我要强调一下,像编写Shell, 我们经常是面向过程的,建议以函数为单位,这样脚本非常的清晰可读。赶紧执行以下看看效果吧。[root@LinuxNode2 shell]# ./shell_template.sh
Usage: ./shell_template.sh {backup}
3、不加锁的Shell脚本就是让别人耍流氓
你编写的脚本能多个人同时执行吗?如果不能,那么如果多个人一起执行会怎么样呢?想想是不是有点冒冷汗。所以,不要给我们的其它小伙伴留下陷阱。不过如果你公司就你一个运维,真的不用怕吗?试想如果是定时任务再运行这个脚本,上一次没有运行完毕,然后到时间又运行了?然后,然后,然后,后果好可怕。#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
echo $"Usage: $0 {backup}"
}

shell_lock(){
touch ${LOCK_FILE}
}

shell_unlock(){
rm -f ${LOCK_FILE}
}

# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
if [ -f "$LOCK_FILE" ];then
shell_log "${SHELL_NAME} is running"
echo "${SHELL_NAME}" is running && exit
fi
shell_log "mysql backup start"
shell_lock
sleep 10
shell_log "mysql backup stop"
shell_unlock
}

# Main Function
main(){
case $1 in
backup)
mysql_backup
;;
*)
shell_usage;
esac
}

#Exec
main $1我为脚本增加了两个函数shell_lock和shell_unlock非常简单,就是创建一个锁文件。然后再执行的时候先判断锁文件是否存在,如果存在说明有其它用户在执行,就退出。如果没有自己创建锁文件,开始执行,执行完毕删除锁文件。
 
好的,现在你可以赶紧再开一个窗口试试能不能执行这个脚本,或者到/tmp目录下看看是否创建了锁文件。请注意:如果已知的异常退出,一定也要删除这个锁文件。
 

做好事必须留名

对于一个功能脚本来说,貌似还少了点什么。对,就是注释!我们要说明白这个脚本是干啥的。或者以后你离职后,别人看到这个脚本之后,我擦,这么牛掰的脚本是谁写的呢?不要怕,写上你的大名。#######################################################
# $Name: shell_template.sh
# $Version: v1.0
# $Function: Backup MySQL Databases Template Script
# $Author: Jason Zhao
# $organization: https://www.unixhot.com/
# $Create Date: 2016-08-27
# $Description: You know what i mean,hehe
#######################################################当然还有很多编写脚本的技巧,没法一一描述,不过如果能掌握上面的三种技巧,立马感觉编写的脚本有点高大上,有木有?

文章作者:赵班长
分享原文:http://dwz.cn/4JDIFv  查看全部
liumang.jpg


声明


大家都是文明人,尤其是做运维的,那叫一个斯文啊。怎么能耍流氓呢?赶紧看看,编写 SHELL 脚本如何能够不耍流氓。


Mysql备份脚本案例


1、不记录日志的 SHELL 脚本就是耍流氓!
我们经常在工作中会遇到一个苦恼的事情,一个 Shell 脚本到底干了什么,什么时候开始执行,什么时候结束的。尤其是数据库备份,我们想知道我们的 MySQL 数据库备份时间。所以给脚本加日志显得尤为重要。那么我们的脚本应该有一个日志的函数,专门用于记录日志:
#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

shell_log "shell beginning, Write log test"
shell_log "shell success, Write log test"


上面的脚本我编写了一个日志函数shell_log,每次记录日志,我们直接执行shell_log把日志内容当作第一个参数传给它就可以了,赶紧试试。
[root@LinuxNode2 shell]# cat shell_template.sh.log
2016-08-27 06-01-19 : shell_template.sh :shell beginning ,write log test
2016-08-27 06-01-19 : shell_template.sh :shell success ,write log test

2、直接就能执行的Shell脚本很容易耍流氓?
一个脚本直接就能执行?难道不是直接就能执行吗?试想,你临时编写了一个特别重要的脚本,干的事情可能有破坏性,一不小心被别人./执行了怎么办呢?而且很多时候我们一个脚本的功能可能有多个,所以我们有必要让用户可以选择进行执行。
#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log 
shell_log(){
    LOG_INFO=$1
    echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
    echo $"Usage: $0 {backup}"
}


# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
    shell_log "mysql backup start"
    shell_log "mysql backup stop"
}

# Main Function
main(){
    case $1 in
        backup)
            mysql_backup
            ;;
        *)
            shell_usage;
    esac
}

#Exec
main $1


上面的脚本我们编写了shell_usage函数,用来告诉用户,这个脚本的使用方法。同时,我要强调一下,像编写Shell, 我们经常是面向过程的,建议以函数为单位,这样脚本非常的清晰可读。赶紧执行以下看看效果吧。
[root@LinuxNode2 shell]# ./shell_template.sh
Usage: ./shell_template.sh {backup}

3、不加锁的Shell脚本就是让别人耍流氓
你编写的脚本能多个人同时执行吗?如果不能,那么如果多个人一起执行会怎么样呢?想想是不是有点冒冷汗。所以,不要给我们的其它小伙伴留下陷阱。不过如果你公司就你一个运维,真的不用怕吗?试想如果是定时任务再运行这个脚本,上一次没有运行完毕,然后到时间又运行了?然后,然后,然后,后果好可怕。
#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
echo $"Usage: $0 {backup}"
}

shell_lock(){
touch ${LOCK_FILE}
}

shell_unlock(){
rm -f ${LOCK_FILE}
}

# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
if [ -f "$LOCK_FILE" ];then
shell_log "${SHELL_NAME} is running"
echo "${SHELL_NAME}" is running && exit
fi
shell_log "mysql backup start"
shell_lock
sleep 10
shell_log "mysql backup stop"
shell_unlock
}

# Main Function
main(){
case $1 in
backup)
mysql_backup
;;
*)
shell_usage;
esac
}

#Exec
main $1
我为脚本增加了两个函数shell_lock和shell_unlock非常简单,就是创建一个锁文件。然后再执行的时候先判断锁文件是否存在,如果存在说明有其它用户在执行,就退出。如果没有自己创建锁文件,开始执行,执行完毕删除锁文件。
 
好的,现在你可以赶紧再开一个窗口试试能不能执行这个脚本,或者到/tmp目录下看看是否创建了锁文件。请注意:如果已知的异常退出,一定也要删除这个锁文件。
 


做好事必须留名


对于一个功能脚本来说,貌似还少了点什么。对,就是注释!我们要说明白这个脚本是干啥的。或者以后你离职后,别人看到这个脚本之后,我擦,这么牛掰的脚本是谁写的呢?不要怕,写上你的大名。
#######################################################
# $Name: shell_template.sh
# $Version: v1.0
# $Function: Backup MySQL Databases Template Script
# $Author: Jason Zhao
# $organization: https://www.unixhot.com/
# $Create Date: 2016-08-27
# $Description: You know what i mean,hehe
#######################################################
当然还有很多编写脚本的技巧,没法一一描述,不过如果能掌握上面的三种技巧,立马感觉编写的脚本有点高大上,有木有?


文章作者:赵班长
分享原文http://dwz.cn/4JDIFv 


分享个基于sendclound的邮件群发软件 大家提点意见

回复

开源技术Nappywu 发起了问题 • 1 人关注 • 0 个回复 • 206 次浏览 • 2016-11-25 15:51 • 来自相关话题

Shell终端输出字体颜色记录

回复

开源技术Geek小A 发起了问题 • 1 人关注 • 0 个回复 • 554 次浏览 • 2016-07-15 12:05 • 来自相关话题

常用Linux系统Debug命令

开源技术Geek小A 发表了文章 • 0 个评论 • 467 次浏览 • 2016-07-09 13:06 • 来自相关话题

1、查看TCP连接状态netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -cnetstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c 
2、查找请求80端口最多的20个IP连接netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A,i}' |sort -rn|head -n20tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -n 20
3、查找较多time_wait连接netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20
4、找查较多的SYN连接netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
5、根据端口列进程netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1
6、获取Web访问前10位的ip地址
cat access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -n 10
cat access.log|awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}'
​7、访问次数最多的文件或页面,取前20
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20
8、列出传输最大的几个rar文件
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20
 
9、列出输出大于200000byte(约200kb)的rar文件以及对应文件发生次数
cat access.log |awk '($10 > 200000 && $7~/\.rar/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100
10、如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100


11、列出最最耗时的页面(超过60秒的)的以及对应页面发生次数
cat access.log |awk '($NF > 60 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100
 12、列出传输时间超过 30 秒的文件
cat access.log |awk '($NF > 30){print $7}'|sort -n|uniq -c|sort -nr|head -n 20
13、统计网站流量(G)
cat access.log |awk '{sum+=$10} END {print sum/1024/1024/1024}'
14、统计404的连接
awk '($9 ~/404/)' access.log | awk '{print $9,$7}' | sort
15、统计http status
cat access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn
16、查看是哪些爬虫在抓取内容
tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
 
17、查看数据库执行的sql语句
tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'
18、按域统计流量
zcat squid_access.log.tar.gz| awk '{print $10,$7}' |awk 'BEGIN{FS="[ /]"}{trfc[$4]+=$1}END{for(domain in trfc){printf "%s\t%d\n",domain,trfc[domain]}}'
19、调试命令
strace -p pid
20、磁盘性能
iostat -x 1 10 查看全部
1、查看TCP连接状态
netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn 
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c
netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn 
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c
 
2、查找请求80端口最多的20个IP连接
netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A,i}' |sort -rn|head -n20
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -n 20

3、查找较多time_wait连接
netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20

4、找查较多的SYN连接
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more

5、根据端口列进程
netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1

6、获取Web访问前10位的ip地址
cat access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -n 10
cat access.log|awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}'

​7、访问次数最多的文件或页面,取前20
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20

8、列出传输最大的几个rar文件
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20

 
9、列出输出大于200000byte(约200kb)的rar文件以及对应文件发生次数
cat access.log |awk '($10 > 200000 && $7~/\.rar/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100

10、如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100


11、列出最最耗时的页面(超过60秒的)的以及对应页面发生次数
cat access.log |awk '($NF > 60 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100

 12、列出传输时间超过 30 秒的文件
cat access.log |awk '($NF > 30){print $7}'|sort -n|uniq -c|sort -nr|head -n 20

13、统计网站流量(G)
cat access.log |awk '{sum+=$10} END {print sum/1024/1024/1024}'

14、统计404的连接
awk '($9 ~/404/)' access.log | awk '{print $9,$7}' | sort

15、统计http status
cat access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn

16、查看是哪些爬虫在抓取内容
tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'

 
17、查看数据库执行的sql语句
tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'

18、按域统计流量
zcat squid_access.log.tar.gz| awk '{print $10,$7}' |awk 'BEGIN{FS="[ /]"}{trfc[$4]+=$1}END{for(domain in trfc){printf "%s\t%d\n",domain,trfc[domain]}}'

19、调试命令
strace -p pid

20、磁盘性能
iostat -x 1 10

解决Apache child pid 22404 exit signal Segmentation fault (11)错误

开源技术Ansible 发表了文章 • 0 个评论 • 607 次浏览 • 2016-07-07 22:31 • 来自相关话题

新搭建的测试环境用的Apache/2.2.15,然后测试的时候,页面报502,最后查看Apache的log日志如下:
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)
为了解决这个问题,网上搜了几个方法都无法解决,然后网上有人说是Apache的一个bug,是内存问题,最后我只能写个脚本处理。
 
1、检查服务器
[root@uweb1 atom]# cat /etc/issue
CentOS release 6.5 (Final)
Kernel \r on an \m

[root@uweb1 atom]# uname -r
2.6.32-573.22.1.el6.x86_64[root@uweb1 atom]# slabtop
Active / Total Objects (% used) : 262463 / 284128 (92.4%)
Active / Total Slabs (% used) : 18670 / 18670 (100.0%)
Active / Total Caches (% used) : 92 / 172 (53.5%)
Active / Total Size (% used) : 74471.91K / 77331.03K (96.3%)
Minimum / Average / Maximum Object : 0.02K / 0.27K / 4096.00K

OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
103452 103431 99% 0.10K 2796 37 11184K buffer_head
34000 33764 99% 0.98K 8500 4 34000K ext4_inode_cache
33240 33240 100% 0.19K 1662 20 6648K dentry
17024 16889 99% 0.03K 152 112 608K size-32
15323 7993 52% 0.05K 199 77 796K anon_vma_chain
13148 8203 62% 0.20K 692 19 2768K vm_area_struct
11151 9723 87% 0.06K 189 59 756K size-64
7616 7071 92% 0.55K 1088 7 4352K radix_tree_node
7261 7251 99% 0.07K 137 53 548K selinux_inode_security
6767 3720 54% 0.05K 101 67 404K anon_vma
6534 6527 99% 0.14K 242 27 968K sysfs_dir_cache
4404 4404 100% 0.58K 734 6 2936K inode_cache
3816 3767 98% 0.07K 72 53 288K Acpi-Operand
2580 1833 71% 0.12K 86 30 344K size-128
2400 1523 63% 0.25K 160 15 640K filp
2208 2199 99% 0.04K 24 92 96K Acpi-Namespace
2080 2008 96% 0.19K 104 20 416K size-192
1782 1782 100% 0.64K 297 6 1188K proc_inode_cache
756 744 98% 1.00K 189 4 756K size-1024 
其实apache报[notice] child pid 1421 exit signal Segmentation fault (11),绝大部分是内存泄露的问题,网上的禁止proxy和cache模块,经过我试验没有效果,修改php内存也一样。
 
2、解决内存泄露脚本
#!/bin/bash
time=`date`
echo $time > /tmp/clear_cached.txt

echo "total/used/free/shared/buffers/cached" >> /tmp/clear_cached.txt
echo "Cleart Before" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt
sync;
echo 2 > /proc/sys/vm/drop_caches;
echo 0 > /proc/sys/vm/drop_caches;
echo "Clear After" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt 查看全部
新搭建的测试环境用的Apache/2.2.15,然后测试的时候,页面报502,最后查看Apache的log日志如下:
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)

为了解决这个问题,网上搜了几个方法都无法解决,然后网上有人说是Apache的一个bug,是内存问题,最后我只能写个脚本处理。
 
1、检查服务器
[root@uweb1 atom]# cat /etc/issue
CentOS release 6.5 (Final)
Kernel \r on an \m

[root@uweb1 atom]# uname -r
2.6.32-573.22.1.el6.x86_64
[root@uweb1 atom]# slabtop
Active / Total Objects (% used) : 262463 / 284128 (92.4%)
Active / Total Slabs (% used) : 18670 / 18670 (100.0%)
Active / Total Caches (% used) : 92 / 172 (53.5%)
Active / Total Size (% used) : 74471.91K / 77331.03K (96.3%)
Minimum / Average / Maximum Object : 0.02K / 0.27K / 4096.00K

OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
103452 103431 99% 0.10K 2796 37 11184K buffer_head
34000 33764 99% 0.98K 8500 4 34000K ext4_inode_cache
33240 33240 100% 0.19K 1662 20 6648K dentry
17024 16889 99% 0.03K 152 112 608K size-32
15323 7993 52% 0.05K 199 77 796K anon_vma_chain
13148 8203 62% 0.20K 692 19 2768K vm_area_struct
11151 9723 87% 0.06K 189 59 756K size-64
7616 7071 92% 0.55K 1088 7 4352K radix_tree_node
7261 7251 99% 0.07K 137 53 548K selinux_inode_security
6767 3720 54% 0.05K 101 67 404K anon_vma
6534 6527 99% 0.14K 242 27 968K sysfs_dir_cache
4404 4404 100% 0.58K 734 6 2936K inode_cache
3816 3767 98% 0.07K 72 53 288K Acpi-Operand
2580 1833 71% 0.12K 86 30 344K size-128
2400 1523 63% 0.25K 160 15 640K filp
2208 2199 99% 0.04K 24 92 96K Acpi-Namespace
2080 2008 96% 0.19K 104 20 416K size-192
1782 1782 100% 0.64K 297 6 1188K proc_inode_cache
756 744 98% 1.00K 189 4 756K size-1024
 
其实apache报[notice] child pid 1421 exit signal Segmentation fault (11),绝大部分是内存泄露的问题,网上的禁止proxy和cache模块,经过我试验没有效果,修改php内存也一样。
 
2、解决内存泄露脚本
#!/bin/bash
time=`date`
echo $time > /tmp/clear_cached.txt

echo "total/used/free/shared/buffers/cached" >> /tmp/clear_cached.txt
echo "Cleart Before" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt
sync;
echo 2 > /proc/sys/vm/drop_caches;
echo 0 > /proc/sys/vm/drop_caches;
echo "Clear After" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt

AWK计算操作实践笔记

开源技术chris 发表了文章 • 0 个评论 • 409 次浏览 • 2016-06-17 18:00 • 来自相关话题

有列纯数字的文本(在之前可以通过各种手段过滤出只有数字这一列),比如它代表的是网站在线数,内容如下:127809
16813
551646
18858
18977
29369
23563
56302
11823
20212
149427
146515 一、求和awk '{sum+=$1} END {print "Sum = ", sum}'
 二、求平均awk '{sum+=$1} END {print "Average = ", sum/NR}'如果有浮点的话还需要 .2%之类格式支持
 
三、求最大值awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'
四、求最小值(min的初始值设置一个超大数即可)awk 'BEGIN {min = 2000000000} {if ($1<min) min=$1 fi} END {print "Min=", min}'
 五、案例分析
部分原始数据如下:09:14:00.500 3279.20 5 3279.80 29 3279.80 73 28715
09:15:00.500 3279.00 14 3279.80 9 3279.80 134 28723
09:15:01.0 3279.00 11 3279.20 24 3279.20 155 28721
09:15:01.500 3279.00 3 3279.20 15 3279.20 172 28715
09:15:02.0 3278.20 7 3278.80 7 3279.20 190 28719
09:15:02.500 3278.20 2 3278.60 1 3278.80 205 28721
09:15:03.0 3278.40 1 3278.60 25 3278.60 215 28727
09:15:03.500 3278.00 88 3278.60 13 3278.60 236 28729
09:15:04.0 3278.00 88 3278.40 12 3278.20 239 28728
09:15:04.500 3278.20 2 3278.40 12 3278.20 255 28724
09:15:05.0 3278.00 78 3278.20 1 3278.00 268 28724
09:15:05.500 3278.00 71 3278.40 10 3278.20 279 28726
09:15:06.0 3278.00 65 3278.20 14 3278.00 288 28726
09:15:06.500 3278.00 58 3278.20 16 3278.00 295 28722
09:15:07.0 3278.00 48 3278.20 5 3278.20 317 28728
09:15:07.500 3278.00 44 3278.40 8 3278.00 337 28733
09:15:08.0 3278.00 39 3278.40 8 3278.00 344 28727
09:15:08.500 3278.20 1 3278.40 7 3278.20 351 28729
09:15:09.0 3278.20 1 3278.40 5 3278.20 361 28726
09:15:09.500 3278.00 29 3278.40 4 3278.20 368 28726第一步已经实现了对原始数据每分钟最大值、最小值、平均值的统计。我把第一次统计后的数据列出来:09:19 3297.80 3296.00 3296.8
09:20 3299.00 3296.60 3297.8
09:21 3298.40 3296.20 3296.9
09:22 3299.80 3297.20 3298.4
09:23 3299.20 3296.20 3298.3
09:24 3299.00 3297.20 3298.1$1: 时间, $2: 分钟最大值, $3: 分钟最小值, $4: 分钟平均值
 
以上数据通过如下方式实现的:#!/bin/sh
srcpath=./src/
despath=./des/
for file in $(ls -1 -F ${srcpath} | grep -v [/$]);do
# 第一步:处理原始数据
# 通过substr来截取时间字段的[小时:分钟]
# 处理后的数据格式为 time max min arg ;共4个字段
# 最后把统计后的数据保存至目标临时文件
# 使用了三元运算符
awk '{
time=substr($1,1,5)
count[time]++
max[time]=$6>max[time]?$6:max[time]
min[time]=(!length(min[time])||$6<min[time])?$6:min[time]
sum[time]+=$6
}
END{
for(i in count) {
print i,max,min,sum/count
}
}' ${srcpath}${file}|sort> ${despath}${file}_tmp
done说明:把以上数据做个累计最大值和累计最小值统计。
初始化统计的时候,累计最值和每分钟最值是一样的.
要求输出如下格式数据:09:19 3297.80 3296.00 3296.8 3297.80 3296.00
09:20 3299.00 3296.60 3297.8 3299.00 3296.00
09:21 3298.40 3296.20 3296.9 3299.00 3296.00
09:22 3299.80 3297.20 3298.4 3299.80 3296.00
09:23 3299.20 3296.20 3298.3 3299.80 3296.00
09:24 3299.00 3297.20 3298.1 3299.80 3296.00 查看全部
有列纯数字的文本(在之前可以通过各种手段过滤出只有数字这一列),比如它代表的是网站在线数,内容如下:
127809 
16813
551646
18858
18977
29369
23563
56302
11823
20212
149427
146515
一、求和
awk '{sum+=$1} END {print "Sum = ", sum}'

 二、求平均
awk '{sum+=$1} END {print "Average = ", sum/NR}'
如果有浮点的话还需要 .2%之类格式支持
 
三、求最大值
awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'

四、求最小值(min的初始值设置一个超大数即可)
awk 'BEGIN {min = 2000000000} {if ($1<min) min=$1 fi} END {print "Min=", min}'

 五、案例分析
部分原始数据如下:
09:14:00.500        3279.20        5        3279.80         29                3279.80        73        28715
09:15:00.500 3279.00 14 3279.80 9 3279.80 134 28723
09:15:01.0 3279.00 11 3279.20 24 3279.20 155 28721
09:15:01.500 3279.00 3 3279.20 15 3279.20 172 28715
09:15:02.0 3278.20 7 3278.80 7 3279.20 190 28719
09:15:02.500 3278.20 2 3278.60 1 3278.80 205 28721
09:15:03.0 3278.40 1 3278.60 25 3278.60 215 28727
09:15:03.500 3278.00 88 3278.60 13 3278.60 236 28729
09:15:04.0 3278.00 88 3278.40 12 3278.20 239 28728
09:15:04.500 3278.20 2 3278.40 12 3278.20 255 28724
09:15:05.0 3278.00 78 3278.20 1 3278.00 268 28724
09:15:05.500 3278.00 71 3278.40 10 3278.20 279 28726
09:15:06.0 3278.00 65 3278.20 14 3278.00 288 28726
09:15:06.500 3278.00 58 3278.20 16 3278.00 295 28722
09:15:07.0 3278.00 48 3278.20 5 3278.20 317 28728
09:15:07.500 3278.00 44 3278.40 8 3278.00 337 28733
09:15:08.0 3278.00 39 3278.40 8 3278.00 344 28727
09:15:08.500 3278.20 1 3278.40 7 3278.20 351 28729
09:15:09.0 3278.20 1 3278.40 5 3278.20 361 28726
09:15:09.500 3278.00 29 3278.40 4 3278.20 368 28726
第一步已经实现了对原始数据每分钟最大值、最小值、平均值的统计。我把第一次统计后的数据列出来:
09:19  3297.80  3296.00  3296.8
09:20 3299.00 3296.60 3297.8
09:21 3298.40 3296.20 3296.9
09:22 3299.80 3297.20 3298.4
09:23 3299.20 3296.20 3298.3
09:24 3299.00 3297.20 3298.1
$1: 时间, $2: 分钟最大值, $3: 分钟最小值, $4: 分钟平均值
 
以上数据通过如下方式实现的:
#!/bin/sh
srcpath=./src/
despath=./des/
for file in $(ls -1 -F ${srcpath} | grep -v [/$]);do
# 第一步:处理原始数据
# 通过substr来截取时间字段的[小时:分钟]
# 处理后的数据格式为 time max min arg ;共4个字段
# 最后把统计后的数据保存至目标临时文件
# 使用了三元运算符
awk '{
time=substr($1,1,5)
count[time]++
max[time]=$6>max[time]?$6:max[time]
min[time]=(!length(min[time])||$6<min[time])?$6:min[time]
sum[time]+=$6
}
END{
for(i in count) {
print i,max,min,sum/count
}
}' ${srcpath}${file}|sort> ${despath}${file}_tmp
done
说明:把以上数据做个累计最大值和累计最小值统计。
初始化统计的时候,累计最值和每分钟最值是一样的.
要求输出如下格式数据:
09:19  3297.80  3296.00  3296.8  3297.80  3296.00
09:20 3299.00 3296.60 3297.8 3299.00 3296.00
09:21 3298.40 3296.20 3296.9 3299.00 3296.00
09:22 3299.80 3297.20 3298.4 3299.80 3296.00
09:23 3299.20 3296.20 3298.3 3299.80 3296.00
09:24 3299.00 3297.20 3298.1 3299.80 3296.00

Linux增加虚拟内存swap脚本

开源技术being 发表了文章 • 0 个评论 • 467 次浏览 • 2016-05-16 10:09 • 来自相关话题

#!/bin/bash

#增加1G的swap空间
dd if=/dev/zero of=/swapfile bs=1MB count=1024

#制作一个swap文件
mkswap /swapfile

#启动swap分区
swapon /swapfile

#添加开机自启
echo '/swapfile none swap defaults 0 0' >> /etc/fstab 查看全部
#!/bin/bash

#增加1G的swap空间
dd if=/dev/zero of=/swapfile bs=1MB count=1024

#制作一个swap文件
mkswap /swapfile

#启动swap分区
swapon /swapfile

#添加开机自启
echo '/swapfile none swap defaults 0 0' >> /etc/fstab

文本每行加''引号和合并为一行并以逗号分隔

开源技术采菊篱下 回复了问题 • 2 人关注 • 1 个回复 • 746 次浏览 • 2016-04-15 10:30 • 来自相关话题

Shell中数学计算总结

开源技术Ansible 发表了文章 • 1 个评论 • 472 次浏览 • 2016-03-22 00:39 • 来自相关话题

Shell中的赋值和操作默认都是字符串处理,在此记下shell中进行数学运算的几个特殊方法,以后用到的时候可以来看看:

错误方法举例​

A:
var=1+1
echo $var

输出的结果是1+1,悲剧,呵呵B:
var=1
var=$var+1
echo $var

输出结果是1+1,依然悲剧,呵呵

正确方法

A: 使用let
var=1
let "var+=1"
echo $var

输出结果为2,这次没有悲剧注意:
[]经我测试let几乎支持所有的运算符,在网上看到一篇文章说“let不支持++、--和逗号、(、)”,但经我测试自加、自减、以及括号的优先级都得到了很好的支持[/][]方幂运算应使用“”[/][]参数在表达式中直接访问,不必加$[/][]一般情况下算数表达式可以不加双引号,但是若表达式中有bash中的关键字则需加上[/][]let后的表达式只能进行整数运算[/]
B: 使用(())
var=1
((var+=1))
echo $var

输出结果为2注意:
(())的使用方法与let完全相同
C: 使用$[]
var=1
var=$[$var+1]
echo $var

输出结果位2注意:
[]$[]将中括号内的表达式作为数学运算先计算结果再输出[/][]对$[]中的变量进行访问时前面需要加$[/][]$[]支持的运算符与let相同,但也只支持整数运算[/]
D: 使用expr
var=1
var=`expr $var + 1`
echo $var

输出结果为2注意:
[]expr后的表达式个符号间需用空格隔开[/][]expr支持的操作符有: |、&、<、<=、=、!=、>=、>、+、-、、/、%[/*][]expr支持的操作符中所在使用时需用\进行转义的有:|、&、<、<=、>=、>、[/*][]expr同样只支持整数运算[/]
E:使用bc(可以进行浮点数计算)
var=1
var=`echo "$var+1"|bc`
echo $var

输出结果为2介绍:
bc是linux下的一个简单计算器,支持浮点数计算,在命令行下输入bc即进入计算器程序,而我们想在程序中直接进行浮点数计算时,利用一个简单的管道即可解决问题。注意:
[]经我测试bc支持除位操作运算符之外的所有运算符。[/][]bc中要使用scale进行精度设置[/]
浮点数计算实例:
var=3.14
var=`echo "scale=2;$var*3"|bc`
echo $var

输出结果为9.42F:使用awk(可进行浮点数计算)​
var=1
var=`echo "$var 1"|awk '{printf("%g",$1*$2)}'`
echo $var

输出结果为2介绍:
awk是一种文本处理工具,同时也是一种程序设计语言,作为一种程序设计语言,awk支持多种运算,而我们可以利用awk来进行浮点数计算,和上面bc一样,通过一个简单的管道,我们便可在程序中直接调用awk进行浮点数计算。注意:
[]awk支持除微操作运算符之外的所有运算符[/][]awk内置有log、sqr、cos、sin等等函数[/]
浮点数计算实例:
var=3.14
var=`echo "$var 2"|awk '{printf("%g",sin($1/$2))}'`
echo $var

输出结果为1

总结​

终于把所有搜集到的资料看完,最后总结分享给大家,以后再遇到shell计算问题,就可以直接用了! 查看全部
Shell中的赋值和操作默认都是字符串处理,在此记下shell中进行数学运算的几个特殊方法,以后用到的时候可以来看看:


错误方法举例​


A:
 var=1+1
echo $var

输出的结果是1+1,悲剧,呵呵
B:
var=1
var=$var+1
echo $var

输出结果是1+1,依然悲剧,呵呵


正确方法


A: 使用let
var=1
let "var+=1"
echo $var

输出结果为2,这次没有悲剧
注意:
    []经我测试let几乎支持所有的运算符,在网上看到一篇文章说“let不支持++、--和逗号、(、)”,但经我测试自加、自减、以及括号的优先级都得到了很好的支持[/][]方幂运算应使用“”[/][]参数在表达式中直接访问,不必加$[/][]一般情况下算数表达式可以不加双引号,但是若表达式中有bash中的关键字则需加上[/][]let后的表达式只能进行整数运算[/]

B: 使用(())
var=1
((var+=1))
echo $var

输出结果为2
注意:
(())的使用方法与let完全相同
C: 使用$[]
var=1
var=$[$var+1]
echo $var

输出结果位2
注意:
    []$[]将中括号内的表达式作为数学运算先计算结果再输出[/][]对$[]中的变量进行访问时前面需要加$[/][]$[]支持的运算符与let相同,但也只支持整数运算[/]

D: 使用expr
var=1
var=`expr $var + 1`
echo $var

输出结果为2
注意:
    []expr后的表达式个符号间需用空格隔开[/][]expr支持的操作符有: |、&、<、<=、=、!=、>=、>、+、-、、/、%[/*][]expr支持的操作符中所在使用时需用\进行转义的有:|、&、<、<=、>=、>、[/*][]expr同样只支持整数运算[/]

E:使用bc(可以进行浮点数计算)
var=1
var=`echo "$var+1"|bc`
echo $var

输出结果为2
介绍:
bc是linux下的一个简单计算器,支持浮点数计算,在命令行下输入bc即进入计算器程序,而我们想在程序中直接进行浮点数计算时,利用一个简单的管道即可解决问题。
注意:
    []经我测试bc支持除位操作运算符之外的所有运算符。[/][]bc中要使用scale进行精度设置[/]

浮点数计算实例:
var=3.14
var=`echo "scale=2;$var*3"|bc`
echo $var

输出结果为9.42
F:使用awk(可进行浮点数计算)​
var=1
var=`echo "$var 1"|awk '{printf("%g",$1*$2)}'`
echo $var

输出结果为2
介绍:
awk是一种文本处理工具,同时也是一种程序设计语言,作为一种程序设计语言,awk支持多种运算,而我们可以利用awk来进行浮点数计算,和上面bc一样,通过一个简单的管道,我们便可在程序中直接调用awk进行浮点数计算。
注意:
    []awk支持除微操作运算符之外的所有运算符[/][]awk内置有log、sqr、cos、sin等等函数[/]

浮点数计算实例:
var=3.14
var=`echo "$var 2"|awk '{printf("%g",sin($1/$2))}'`
echo $var

输出结果为1


总结​


终于把所有搜集到的资料看完,最后总结分享给大家,以后再遇到shell计算问题,就可以直接用了!

Shell数组详解

开源技术Ansible 发表了文章 • 1 个评论 • 547 次浏览 • 2016-03-21 23:34 • 来自相关话题

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。

数组定义

在Shell中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:array_name=(value1 ... valuen)例如:array_name=(value0 value1 value2 value3)或者array_name=(
value0
value1
value2
value3
)还可以单独定义数组的各个分量:array_name[0]=value0
array_name[1]=value1
array_name[2]=value2可以不使用连续的下标,而且下标的范围没有限制。

读取数组

读取数组元素值的一般格式是:${array_name[index]}例如:result=${array[2]}举个栗子:#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Index: ${IT[0]}"
echo "Second Index: ${IT[1]}"运行脚本,输出:First Index: hadoop
Second Index: cloud用${数组名[下标]} 下标是从0开始  下标是:*或者@ 得到整个数组内容
举个栗子:
[root@workhost ansible]# vim test.sh
#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Method: ${IT[*]}"
echo "Second Method: ${IT[@]}"

[root@workhost ansible]# bash test.sh
First Method: hadoop cloud docker virtual web
Second Method: hadoop cloud docker virtual web

获取数组的长度

# 取得整个数组的长度
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
举个栗子:





删除数组

unset array_name
unset array_name[n]举个栗子:





特殊用法

分片:
[root@workhost ~]$ a=(1 2 3 4 5)
[root@workhost ~]$ echo ${a[@]:0:3}
1 2 3
[root@workhost ~]$ echo ${a[@]:1:4}
2 3 4 5

[root@workhost ~]$ c=(${a[@]:1:4})
[root@workhost ~]$ echo ${#c[@]}
4
[root@workhost ~]$ echo ${c}
2 3 4 5直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用"空格"分开,因此如果加上"()",将得到切片数组,上面例子:c就是一个新数据。
替换:
[root@workhost ~]$ a=(1 2 3 4 5)
[root@workhost ~]$ echo ${a[@]/3/100}
1 2 100 4 5
[root@workhost ~]$ echo ${a[@]}
1 2 3 4 5

[root@workhost ~]$ a=(${a[@]/3/100})
[root@workhost ~]$ echo ${a[@]}
1 2 100 4 5调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,可以看上面例子,重新定义数据。
  查看全部
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。


数组定义


在Shell中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
array_name=(value1 ... valuen)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
可以不使用连续的下标,而且下标的范围没有限制。


读取数组


读取数组元素值的一般格式是:
${array_name[index]}
例如:
result=${array[2]}
举个栗子:
#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Index: ${IT[0]}"
echo "Second Index: ${IT[1]}"
运行脚本,输出:
First Index: hadoop
Second Index: cloud
用${数组名[下标]} 下标是从0开始  下标是:*或者@ 得到整个数组内容
举个栗子:
[root@workhost ansible]# vim test.sh
#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Method: ${IT[*]}"
echo "Second Method: ${IT[@]}"

[root@workhost ansible]# bash test.sh
First Method: hadoop cloud docker virtual web
Second Method: hadoop cloud docker virtual web


获取数组的长度


# 取得整个数组的长度
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

举个栗子:
len.png


删除数组


unset array_name
unset array_name[n]
举个栗子:
delete_array.png


特殊用法


分片:
[root@workhost ~]$ a=(1 2 3 4 5)
[root@workhost ~]$ echo ${a[@]:0:3}
1 2 3
[root@workhost ~]$ echo ${a[@]:1:4}
2 3 4 5

[root@workhost ~]$ c=(${a[@]:1:4})
[root@workhost ~]$ echo ${#c[@]}
4
[root@workhost ~]$ echo ${c}
2 3 4 5
直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用"空格"分开,因此如果加上"()",将得到切片数组,上面例子:c就是一个新数据。
替换:
[root@workhost ~]$ a=(1 2 3 4 5)    
[root@workhost ~]$ echo ${a[@]/3/100}
1 2 100 4 5
[root@workhost ~]$ echo ${a[@]}
1 2 3 4 5

[root@workhost ~]$ a=(${a[@]/3/100})
[root@workhost ~]$ echo ${a[@]}
1 2 100 4 5
调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,可以看上面例子,重新定义数据。
 
条新动态, 点击查看
Ansible

Ansible 回答了问题 • 2015-10-28 11:03 • 2 个回复 不感兴趣

shell如何截取字符串中的数字

赞同来自:

# cat aa.txt
12345zynet
234game
7903checaht1、替换法
# sed 's///g' aa.txt
12345
234
79032、过滤匹配法
# grep -Eo '+' aa.txt
12345
234
790... 显示全部 »
# cat aa.txt
12345zynet
234game
7903checaht1、替换法
# sed 's///g' aa.txt
12345
234
79032、过滤匹配法
# grep -Eo '+' aa.txt
12345
234
7903

shell如何截取字符串中的数字

开源技术push 回复了问题 • 3 人关注 • 2 个回复 • 926 次浏览 • 2015-10-28 11:11 • 来自相关话题

分享个基于sendclound的邮件群发软件 大家提点意见

回复

开源技术Nappywu 发起了问题 • 1 人关注 • 0 个回复 • 206 次浏览 • 2016-11-25 15:51 • 来自相关话题

Shell终端输出字体颜色记录

回复

开源技术Geek小A 发起了问题 • 1 人关注 • 0 个回复 • 554 次浏览 • 2016-07-15 12:05 • 来自相关话题

文本每行加''引号和合并为一行并以逗号分隔

回复

开源技术采菊篱下 回复了问题 • 2 人关注 • 1 个回复 • 746 次浏览 • 2016-04-15 10:30 • 来自相关话题

shell如何截取字符串中的数字

回复

开源技术push 回复了问题 • 3 人关注 • 2 个回复 • 926 次浏览 • 2015-10-28 11:11 • 来自相关话题

运维如何写出不耍流氓的Shell脚本

开源技术小白菜 发表了文章 • 2 个评论 • 160 次浏览 • 2016-12-02 22:33 • 来自相关话题

声明

大家都是文明人,尤其是做运维的,那叫一个斯文啊。怎么能耍流氓呢?赶紧看看,编写 SHELL 脚本如何能够不耍流氓。

Mysql备份脚本案例

1、不记录日志的 SHELL 脚本就是耍流氓!
我们经常在工作中会遇到一个苦恼的事情,一个 Shell 脚本到底干了什么,什么时候开始执行,什么时候结束的。尤其是数据库备份,我们想知道我们的 MySQL 数据库备份时间。所以给脚本加日志显得尤为重要。那么我们的脚本应该有一个日志的函数,专门用于记录日志:#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

shell_log "shell beginning, Write log test"
shell_log "shell success, Write log test"


上面的脚本我编写了一个日志函数shell_log,每次记录日志,我们直接执行shell_log把日志内容当作第一个参数传给它就可以了,赶紧试试。[root@LinuxNode2 shell]# cat shell_template.sh.log
2016-08-27 06-01-19 : shell_template.sh :shell beginning ,write log test
2016-08-27 06-01-19 : shell_template.sh :shell success ,write log test
2、直接就能执行的Shell脚本很容易耍流氓?
一个脚本直接就能执行?难道不是直接就能执行吗?试想,你临时编写了一个特别重要的脚本,干的事情可能有破坏性,一不小心被别人./执行了怎么办呢?而且很多时候我们一个脚本的功能可能有多个,所以我们有必要让用户可以选择进行执行。#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log 
shell_log(){
    LOG_INFO=$1
    echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
    echo $"Usage: $0 {backup}"
}


# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
    shell_log "mysql backup start"
    shell_log "mysql backup stop"
}

# Main Function
main(){
    case $1 in
        backup)
            mysql_backup
            ;;
        *)
            shell_usage;
    esac
}

#Exec
main $1


上面的脚本我们编写了shell_usage函数,用来告诉用户,这个脚本的使用方法。同时,我要强调一下,像编写Shell, 我们经常是面向过程的,建议以函数为单位,这样脚本非常的清晰可读。赶紧执行以下看看效果吧。[root@LinuxNode2 shell]# ./shell_template.sh
Usage: ./shell_template.sh {backup}
3、不加锁的Shell脚本就是让别人耍流氓
你编写的脚本能多个人同时执行吗?如果不能,那么如果多个人一起执行会怎么样呢?想想是不是有点冒冷汗。所以,不要给我们的其它小伙伴留下陷阱。不过如果你公司就你一个运维,真的不用怕吗?试想如果是定时任务再运行这个脚本,上一次没有运行完毕,然后到时间又运行了?然后,然后,然后,后果好可怕。#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
echo $"Usage: $0 {backup}"
}

shell_lock(){
touch ${LOCK_FILE}
}

shell_unlock(){
rm -f ${LOCK_FILE}
}

# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
if [ -f "$LOCK_FILE" ];then
shell_log "${SHELL_NAME} is running"
echo "${SHELL_NAME}" is running && exit
fi
shell_log "mysql backup start"
shell_lock
sleep 10
shell_log "mysql backup stop"
shell_unlock
}

# Main Function
main(){
case $1 in
backup)
mysql_backup
;;
*)
shell_usage;
esac
}

#Exec
main $1我为脚本增加了两个函数shell_lock和shell_unlock非常简单,就是创建一个锁文件。然后再执行的时候先判断锁文件是否存在,如果存在说明有其它用户在执行,就退出。如果没有自己创建锁文件,开始执行,执行完毕删除锁文件。
 
好的,现在你可以赶紧再开一个窗口试试能不能执行这个脚本,或者到/tmp目录下看看是否创建了锁文件。请注意:如果已知的异常退出,一定也要删除这个锁文件。
 

做好事必须留名

对于一个功能脚本来说,貌似还少了点什么。对,就是注释!我们要说明白这个脚本是干啥的。或者以后你离职后,别人看到这个脚本之后,我擦,这么牛掰的脚本是谁写的呢?不要怕,写上你的大名。#######################################################
# $Name: shell_template.sh
# $Version: v1.0
# $Function: Backup MySQL Databases Template Script
# $Author: Jason Zhao
# $organization: https://www.unixhot.com/
# $Create Date: 2016-08-27
# $Description: You know what i mean,hehe
#######################################################当然还有很多编写脚本的技巧,没法一一描述,不过如果能掌握上面的三种技巧,立马感觉编写的脚本有点高大上,有木有?

文章作者:赵班长
分享原文:http://dwz.cn/4JDIFv  查看全部
liumang.jpg


声明


大家都是文明人,尤其是做运维的,那叫一个斯文啊。怎么能耍流氓呢?赶紧看看,编写 SHELL 脚本如何能够不耍流氓。


Mysql备份脚本案例


1、不记录日志的 SHELL 脚本就是耍流氓!
我们经常在工作中会遇到一个苦恼的事情,一个 Shell 脚本到底干了什么,什么时候开始执行,什么时候结束的。尤其是数据库备份,我们想知道我们的 MySQL 数据库备份时间。所以给脚本加日志显得尤为重要。那么我们的脚本应该有一个日志的函数,专门用于记录日志:
#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

shell_log "shell beginning, Write log test"
shell_log "shell success, Write log test"


上面的脚本我编写了一个日志函数shell_log,每次记录日志,我们直接执行shell_log把日志内容当作第一个参数传给它就可以了,赶紧试试。
[root@LinuxNode2 shell]# cat shell_template.sh.log
2016-08-27 06-01-19 : shell_template.sh :shell beginning ,write log test
2016-08-27 06-01-19 : shell_template.sh :shell success ,write log test

2、直接就能执行的Shell脚本很容易耍流氓?
一个脚本直接就能执行?难道不是直接就能执行吗?试想,你临时编写了一个特别重要的脚本,干的事情可能有破坏性,一不小心被别人./执行了怎么办呢?而且很多时候我们一个脚本的功能可能有多个,所以我们有必要让用户可以选择进行执行。
#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log 
shell_log(){
    LOG_INFO=$1
    echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
    echo $"Usage: $0 {backup}"
}


# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
    shell_log "mysql backup start"
    shell_log "mysql backup stop"
}

# Main Function
main(){
    case $1 in
        backup)
            mysql_backup
            ;;
        *)
            shell_usage;
    esac
}

#Exec
main $1


上面的脚本我们编写了shell_usage函数,用来告诉用户,这个脚本的使用方法。同时,我要强调一下,像编写Shell, 我们经常是面向过程的,建议以函数为单位,这样脚本非常的清晰可读。赶紧执行以下看看效果吧。
[root@LinuxNode2 shell]# ./shell_template.sh
Usage: ./shell_template.sh {backup}

3、不加锁的Shell脚本就是让别人耍流氓
你编写的脚本能多个人同时执行吗?如果不能,那么如果多个人一起执行会怎么样呢?想想是不是有点冒冷汗。所以,不要给我们的其它小伙伴留下陷阱。不过如果你公司就你一个运维,真的不用怕吗?试想如果是定时任务再运行这个脚本,上一次没有运行完毕,然后到时间又运行了?然后,然后,然后,后果好可怕。
#!/bin/bash

# Shell Env
SHELL_NAME="shell_template.sh"
SHELL_DIR="/opt/shell"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"

#Write Log
shell_log(){
LOG_INFO=$1
echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}

# Shell Usage
shell_usage(){
echo $"Usage: $0 {backup}"
}

shell_lock(){
touch ${LOCK_FILE}
}

shell_unlock(){
rm -f ${LOCK_FILE}
}

# Backup MySQL All Database with mysqldump or innobackupex
mysql_backup(){
if [ -f "$LOCK_FILE" ];then
shell_log "${SHELL_NAME} is running"
echo "${SHELL_NAME}" is running && exit
fi
shell_log "mysql backup start"
shell_lock
sleep 10
shell_log "mysql backup stop"
shell_unlock
}

# Main Function
main(){
case $1 in
backup)
mysql_backup
;;
*)
shell_usage;
esac
}

#Exec
main $1
我为脚本增加了两个函数shell_lock和shell_unlock非常简单,就是创建一个锁文件。然后再执行的时候先判断锁文件是否存在,如果存在说明有其它用户在执行,就退出。如果没有自己创建锁文件,开始执行,执行完毕删除锁文件。
 
好的,现在你可以赶紧再开一个窗口试试能不能执行这个脚本,或者到/tmp目录下看看是否创建了锁文件。请注意:如果已知的异常退出,一定也要删除这个锁文件。
 


做好事必须留名


对于一个功能脚本来说,貌似还少了点什么。对,就是注释!我们要说明白这个脚本是干啥的。或者以后你离职后,别人看到这个脚本之后,我擦,这么牛掰的脚本是谁写的呢?不要怕,写上你的大名。
#######################################################
# $Name: shell_template.sh
# $Version: v1.0
# $Function: Backup MySQL Databases Template Script
# $Author: Jason Zhao
# $organization: https://www.unixhot.com/
# $Create Date: 2016-08-27
# $Description: You know what i mean,hehe
#######################################################
当然还有很多编写脚本的技巧,没法一一描述,不过如果能掌握上面的三种技巧,立马感觉编写的脚本有点高大上,有木有?


文章作者:赵班长
分享原文http://dwz.cn/4JDIFv 


常用Linux系统Debug命令

开源技术Geek小A 发表了文章 • 0 个评论 • 467 次浏览 • 2016-07-09 13:06 • 来自相关话题

1、查看TCP连接状态netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -cnetstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c 
2、查找请求80端口最多的20个IP连接netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A,i}' |sort -rn|head -n20tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -n 20
3、查找较多time_wait连接netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20
4、找查较多的SYN连接netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
5、根据端口列进程netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1
6、获取Web访问前10位的ip地址
cat access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -n 10
cat access.log|awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}'
​7、访问次数最多的文件或页面,取前20
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20
8、列出传输最大的几个rar文件
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20
 
9、列出输出大于200000byte(约200kb)的rar文件以及对应文件发生次数
cat access.log |awk '($10 > 200000 && $7~/\.rar/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100
10、如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100


11、列出最最耗时的页面(超过60秒的)的以及对应页面发生次数
cat access.log |awk '($NF > 60 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100
 12、列出传输时间超过 30 秒的文件
cat access.log |awk '($NF > 30){print $7}'|sort -n|uniq -c|sort -nr|head -n 20
13、统计网站流量(G)
cat access.log |awk '{sum+=$10} END {print sum/1024/1024/1024}'
14、统计404的连接
awk '($9 ~/404/)' access.log | awk '{print $9,$7}' | sort
15、统计http status
cat access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn
16、查看是哪些爬虫在抓取内容
tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
 
17、查看数据库执行的sql语句
tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'
18、按域统计流量
zcat squid_access.log.tar.gz| awk '{print $10,$7}' |awk 'BEGIN{FS="[ /]"}{trfc[$4]+=$1}END{for(domain in trfc){printf "%s\t%d\n",domain,trfc[domain]}}'
19、调试命令
strace -p pid
20、磁盘性能
iostat -x 1 10 查看全部
1、查看TCP连接状态
netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn 
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c
netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn 
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c
 
2、查找请求80端口最多的20个IP连接
netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A,i}' |sort -rn|head -n20
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -n 20

3、查找较多time_wait连接
netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20

4、找查较多的SYN连接
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more

5、根据端口列进程
netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1

6、获取Web访问前10位的ip地址
cat access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -n 10
cat access.log|awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}'

​7、访问次数最多的文件或页面,取前20
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20

8、列出传输最大的几个rar文件
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -n 20

 
9、列出输出大于200000byte(约200kb)的rar文件以及对应文件发生次数
cat access.log |awk '($10 > 200000 && $7~/\.rar/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100

10、如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100
cat access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -n 100


11、列出最最耗时的页面(超过60秒的)的以及对应页面发生次数
cat access.log |awk '($NF > 60 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -n 100

 12、列出传输时间超过 30 秒的文件
cat access.log |awk '($NF > 30){print $7}'|sort -n|uniq -c|sort -nr|head -n 20

13、统计网站流量(G)
cat access.log |awk '{sum+=$10} END {print sum/1024/1024/1024}'

14、统计404的连接
awk '($9 ~/404/)' access.log | awk '{print $9,$7}' | sort

15、统计http status
cat access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn

16、查看是哪些爬虫在抓取内容
tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'

 
17、查看数据库执行的sql语句
tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'

18、按域统计流量
zcat squid_access.log.tar.gz| awk '{print $10,$7}' |awk 'BEGIN{FS="[ /]"}{trfc[$4]+=$1}END{for(domain in trfc){printf "%s\t%d\n",domain,trfc[domain]}}'

19、调试命令
strace -p pid

20、磁盘性能
iostat -x 1 10

解决Apache child pid 22404 exit signal Segmentation fault (11)错误

开源技术Ansible 发表了文章 • 0 个评论 • 607 次浏览 • 2016-07-07 22:31 • 来自相关话题

新搭建的测试环境用的Apache/2.2.15,然后测试的时候,页面报502,最后查看Apache的log日志如下:
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)
为了解决这个问题,网上搜了几个方法都无法解决,然后网上有人说是Apache的一个bug,是内存问题,最后我只能写个脚本处理。
 
1、检查服务器
[root@uweb1 atom]# cat /etc/issue
CentOS release 6.5 (Final)
Kernel \r on an \m

[root@uweb1 atom]# uname -r
2.6.32-573.22.1.el6.x86_64[root@uweb1 atom]# slabtop
Active / Total Objects (% used) : 262463 / 284128 (92.4%)
Active / Total Slabs (% used) : 18670 / 18670 (100.0%)
Active / Total Caches (% used) : 92 / 172 (53.5%)
Active / Total Size (% used) : 74471.91K / 77331.03K (96.3%)
Minimum / Average / Maximum Object : 0.02K / 0.27K / 4096.00K

OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
103452 103431 99% 0.10K 2796 37 11184K buffer_head
34000 33764 99% 0.98K 8500 4 34000K ext4_inode_cache
33240 33240 100% 0.19K 1662 20 6648K dentry
17024 16889 99% 0.03K 152 112 608K size-32
15323 7993 52% 0.05K 199 77 796K anon_vma_chain
13148 8203 62% 0.20K 692 19 2768K vm_area_struct
11151 9723 87% 0.06K 189 59 756K size-64
7616 7071 92% 0.55K 1088 7 4352K radix_tree_node
7261 7251 99% 0.07K 137 53 548K selinux_inode_security
6767 3720 54% 0.05K 101 67 404K anon_vma
6534 6527 99% 0.14K 242 27 968K sysfs_dir_cache
4404 4404 100% 0.58K 734 6 2936K inode_cache
3816 3767 98% 0.07K 72 53 288K Acpi-Operand
2580 1833 71% 0.12K 86 30 344K size-128
2400 1523 63% 0.25K 160 15 640K filp
2208 2199 99% 0.04K 24 92 96K Acpi-Namespace
2080 2008 96% 0.19K 104 20 416K size-192
1782 1782 100% 0.64K 297 6 1188K proc_inode_cache
756 744 98% 1.00K 189 4 756K size-1024 
其实apache报[notice] child pid 1421 exit signal Segmentation fault (11),绝大部分是内存泄露的问题,网上的禁止proxy和cache模块,经过我试验没有效果,修改php内存也一样。
 
2、解决内存泄露脚本
#!/bin/bash
time=`date`
echo $time > /tmp/clear_cached.txt

echo "total/used/free/shared/buffers/cached" >> /tmp/clear_cached.txt
echo "Cleart Before" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt
sync;
echo 2 > /proc/sys/vm/drop_caches;
echo 0 > /proc/sys/vm/drop_caches;
echo "Clear After" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt 查看全部
新搭建的测试环境用的Apache/2.2.15,然后测试的时候,页面报502,最后查看Apache的log日志如下:
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22404 exit signal Segmentation fault (11)
[Wed Jul 07 11:36:03 2016] [notice] child pid 22424 exit signal Segmentation fault (11)

为了解决这个问题,网上搜了几个方法都无法解决,然后网上有人说是Apache的一个bug,是内存问题,最后我只能写个脚本处理。
 
1、检查服务器
[root@uweb1 atom]# cat /etc/issue
CentOS release 6.5 (Final)
Kernel \r on an \m

[root@uweb1 atom]# uname -r
2.6.32-573.22.1.el6.x86_64
[root@uweb1 atom]# slabtop
Active / Total Objects (% used) : 262463 / 284128 (92.4%)
Active / Total Slabs (% used) : 18670 / 18670 (100.0%)
Active / Total Caches (% used) : 92 / 172 (53.5%)
Active / Total Size (% used) : 74471.91K / 77331.03K (96.3%)
Minimum / Average / Maximum Object : 0.02K / 0.27K / 4096.00K

OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
103452 103431 99% 0.10K 2796 37 11184K buffer_head
34000 33764 99% 0.98K 8500 4 34000K ext4_inode_cache
33240 33240 100% 0.19K 1662 20 6648K dentry
17024 16889 99% 0.03K 152 112 608K size-32
15323 7993 52% 0.05K 199 77 796K anon_vma_chain
13148 8203 62% 0.20K 692 19 2768K vm_area_struct
11151 9723 87% 0.06K 189 59 756K size-64
7616 7071 92% 0.55K 1088 7 4352K radix_tree_node
7261 7251 99% 0.07K 137 53 548K selinux_inode_security
6767 3720 54% 0.05K 101 67 404K anon_vma
6534 6527 99% 0.14K 242 27 968K sysfs_dir_cache
4404 4404 100% 0.58K 734 6 2936K inode_cache
3816 3767 98% 0.07K 72 53 288K Acpi-Operand
2580 1833 71% 0.12K 86 30 344K size-128
2400 1523 63% 0.25K 160 15 640K filp
2208 2199 99% 0.04K 24 92 96K Acpi-Namespace
2080 2008 96% 0.19K 104 20 416K size-192
1782 1782 100% 0.64K 297 6 1188K proc_inode_cache
756 744 98% 1.00K 189 4 756K size-1024
 
其实apache报[notice] child pid 1421 exit signal Segmentation fault (11),绝大部分是内存泄露的问题,网上的禁止proxy和cache模块,经过我试验没有效果,修改php内存也一样。
 
2、解决内存泄露脚本
#!/bin/bash
time=`date`
echo $time > /tmp/clear_cached.txt

echo "total/used/free/shared/buffers/cached" >> /tmp/clear_cached.txt
echo "Cleart Before" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt
sync;
echo 2 > /proc/sys/vm/drop_caches;
echo 0 > /proc/sys/vm/drop_caches;
echo "Clear After" >> /tmp/clear_cached.txt
free -m|grep Mem: >> /tmp/clear_cached.txt

AWK计算操作实践笔记

开源技术chris 发表了文章 • 0 个评论 • 409 次浏览 • 2016-06-17 18:00 • 来自相关话题

有列纯数字的文本(在之前可以通过各种手段过滤出只有数字这一列),比如它代表的是网站在线数,内容如下:127809
16813
551646
18858
18977
29369
23563
56302
11823
20212
149427
146515 一、求和awk '{sum+=$1} END {print "Sum = ", sum}'
 二、求平均awk '{sum+=$1} END {print "Average = ", sum/NR}'如果有浮点的话还需要 .2%之类格式支持
 
三、求最大值awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'
四、求最小值(min的初始值设置一个超大数即可)awk 'BEGIN {min = 2000000000} {if ($1<min) min=$1 fi} END {print "Min=", min}'
 五、案例分析
部分原始数据如下:09:14:00.500 3279.20 5 3279.80 29 3279.80 73 28715
09:15:00.500 3279.00 14 3279.80 9 3279.80 134 28723
09:15:01.0 3279.00 11 3279.20 24 3279.20 155 28721
09:15:01.500 3279.00 3 3279.20 15 3279.20 172 28715
09:15:02.0 3278.20 7 3278.80 7 3279.20 190 28719
09:15:02.500 3278.20 2 3278.60 1 3278.80 205 28721
09:15:03.0 3278.40 1 3278.60 25 3278.60 215 28727
09:15:03.500 3278.00 88 3278.60 13 3278.60 236 28729
09:15:04.0 3278.00 88 3278.40 12 3278.20 239 28728
09:15:04.500 3278.20 2 3278.40 12 3278.20 255 28724
09:15:05.0 3278.00 78 3278.20 1 3278.00 268 28724
09:15:05.500 3278.00 71 3278.40 10 3278.20 279 28726
09:15:06.0 3278.00 65 3278.20 14 3278.00 288 28726
09:15:06.500 3278.00 58 3278.20 16 3278.00 295 28722
09:15:07.0 3278.00 48 3278.20 5 3278.20 317 28728
09:15:07.500 3278.00 44 3278.40 8 3278.00 337 28733
09:15:08.0 3278.00 39 3278.40 8 3278.00 344 28727
09:15:08.500 3278.20 1 3278.40 7 3278.20 351 28729
09:15:09.0 3278.20 1 3278.40 5 3278.20 361 28726
09:15:09.500 3278.00 29 3278.40 4 3278.20 368 28726第一步已经实现了对原始数据每分钟最大值、最小值、平均值的统计。我把第一次统计后的数据列出来:09:19 3297.80 3296.00 3296.8
09:20 3299.00 3296.60 3297.8
09:21 3298.40 3296.20 3296.9
09:22 3299.80 3297.20 3298.4
09:23 3299.20 3296.20 3298.3
09:24 3299.00 3297.20 3298.1$1: 时间, $2: 分钟最大值, $3: 分钟最小值, $4: 分钟平均值
 
以上数据通过如下方式实现的:#!/bin/sh
srcpath=./src/
despath=./des/
for file in $(ls -1 -F ${srcpath} | grep -v [/$]);do
# 第一步:处理原始数据
# 通过substr来截取时间字段的[小时:分钟]
# 处理后的数据格式为 time max min arg ;共4个字段
# 最后把统计后的数据保存至目标临时文件
# 使用了三元运算符
awk '{
time=substr($1,1,5)
count[time]++
max[time]=$6>max[time]?$6:max[time]
min[time]=(!length(min[time])||$6<min[time])?$6:min[time]
sum[time]+=$6
}
END{
for(i in count) {
print i,max,min,sum/count
}
}' ${srcpath}${file}|sort> ${despath}${file}_tmp
done说明:把以上数据做个累计最大值和累计最小值统计。
初始化统计的时候,累计最值和每分钟最值是一样的.
要求输出如下格式数据:09:19 3297.80 3296.00 3296.8 3297.80 3296.00
09:20 3299.00 3296.60 3297.8 3299.00 3296.00
09:21 3298.40 3296.20 3296.9 3299.00 3296.00
09:22 3299.80 3297.20 3298.4 3299.80 3296.00
09:23 3299.20 3296.20 3298.3 3299.80 3296.00
09:24 3299.00 3297.20 3298.1 3299.80 3296.00 查看全部
有列纯数字的文本(在之前可以通过各种手段过滤出只有数字这一列),比如它代表的是网站在线数,内容如下:
127809 
16813
551646
18858
18977
29369
23563
56302
11823
20212
149427
146515
一、求和
awk '{sum+=$1} END {print "Sum = ", sum}'

 二、求平均
awk '{sum+=$1} END {print "Average = ", sum/NR}'
如果有浮点的话还需要 .2%之类格式支持
 
三、求最大值
awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'

四、求最小值(min的初始值设置一个超大数即可)
awk 'BEGIN {min = 2000000000} {if ($1<min) min=$1 fi} END {print "Min=", min}'

 五、案例分析
部分原始数据如下:
09:14:00.500        3279.20        5        3279.80         29                3279.80        73        28715
09:15:00.500 3279.00 14 3279.80 9 3279.80 134 28723
09:15:01.0 3279.00 11 3279.20 24 3279.20 155 28721
09:15:01.500 3279.00 3 3279.20 15 3279.20 172 28715
09:15:02.0 3278.20 7 3278.80 7 3279.20 190 28719
09:15:02.500 3278.20 2 3278.60 1 3278.80 205 28721
09:15:03.0 3278.40 1 3278.60 25 3278.60 215 28727
09:15:03.500 3278.00 88 3278.60 13 3278.60 236 28729
09:15:04.0 3278.00 88 3278.40 12 3278.20 239 28728
09:15:04.500 3278.20 2 3278.40 12 3278.20 255 28724
09:15:05.0 3278.00 78 3278.20 1 3278.00 268 28724
09:15:05.500 3278.00 71 3278.40 10 3278.20 279 28726
09:15:06.0 3278.00 65 3278.20 14 3278.00 288 28726
09:15:06.500 3278.00 58 3278.20 16 3278.00 295 28722
09:15:07.0 3278.00 48 3278.20 5 3278.20 317 28728
09:15:07.500 3278.00 44 3278.40 8 3278.00 337 28733
09:15:08.0 3278.00 39 3278.40 8 3278.00 344 28727
09:15:08.500 3278.20 1 3278.40 7 3278.20 351 28729
09:15:09.0 3278.20 1 3278.40 5 3278.20 361 28726
09:15:09.500 3278.00 29 3278.40 4 3278.20 368 28726
第一步已经实现了对原始数据每分钟最大值、最小值、平均值的统计。我把第一次统计后的数据列出来:
09:19  3297.80  3296.00  3296.8
09:20 3299.00 3296.60 3297.8
09:21 3298.40 3296.20 3296.9
09:22 3299.80 3297.20 3298.4
09:23 3299.20 3296.20 3298.3
09:24 3299.00 3297.20 3298.1
$1: 时间, $2: 分钟最大值, $3: 分钟最小值, $4: 分钟平均值
 
以上数据通过如下方式实现的:
#!/bin/sh
srcpath=./src/
despath=./des/
for file in $(ls -1 -F ${srcpath} | grep -v [/$]);do
# 第一步:处理原始数据
# 通过substr来截取时间字段的[小时:分钟]
# 处理后的数据格式为 time max min arg ;共4个字段
# 最后把统计后的数据保存至目标临时文件
# 使用了三元运算符
awk '{
time=substr($1,1,5)
count[time]++
max[time]=$6>max[time]?$6:max[time]
min[time]=(!length(min[time])||$6<min[time])?$6:min[time]
sum[time]+=$6
}
END{
for(i in count) {
print i,max,min,sum/count
}
}' ${srcpath}${file}|sort> ${despath}${file}_tmp
done
说明:把以上数据做个累计最大值和累计最小值统计。
初始化统计的时候,累计最值和每分钟最值是一样的.
要求输出如下格式数据:
09:19  3297.80  3296.00  3296.8  3297.80  3296.00
09:20 3299.00 3296.60 3297.8 3299.00 3296.00
09:21 3298.40 3296.20 3296.9 3299.00 3296.00
09:22 3299.80 3297.20 3298.4 3299.80 3296.00
09:23 3299.20 3296.20 3298.3 3299.80 3296.00
09:24 3299.00 3297.20 3298.1 3299.80 3296.00

Linux增加虚拟内存swap脚本

开源技术being 发表了文章 • 0 个评论 • 467 次浏览 • 2016-05-16 10:09 • 来自相关话题

#!/bin/bash

#增加1G的swap空间
dd if=/dev/zero of=/swapfile bs=1MB count=1024

#制作一个swap文件
mkswap /swapfile

#启动swap分区
swapon /swapfile

#添加开机自启
echo '/swapfile none swap defaults 0 0' >> /etc/fstab 查看全部
#!/bin/bash

#增加1G的swap空间
dd if=/dev/zero of=/swapfile bs=1MB count=1024

#制作一个swap文件
mkswap /swapfile

#启动swap分区
swapon /swapfile

#添加开机自启
echo '/swapfile none swap defaults 0 0' >> /etc/fstab

Shell中数学计算总结

开源技术Ansible 发表了文章 • 1 个评论 • 472 次浏览 • 2016-03-22 00:39 • 来自相关话题

Shell中的赋值和操作默认都是字符串处理,在此记下shell中进行数学运算的几个特殊方法,以后用到的时候可以来看看:

错误方法举例​

A:
var=1+1
echo $var

输出的结果是1+1,悲剧,呵呵B:
var=1
var=$var+1
echo $var

输出结果是1+1,依然悲剧,呵呵

正确方法

A: 使用let
var=1
let "var+=1"
echo $var

输出结果为2,这次没有悲剧注意:
[]经我测试let几乎支持所有的运算符,在网上看到一篇文章说“let不支持++、--和逗号、(、)”,但经我测试自加、自减、以及括号的优先级都得到了很好的支持[/][]方幂运算应使用“”[/][]参数在表达式中直接访问,不必加$[/][]一般情况下算数表达式可以不加双引号,但是若表达式中有bash中的关键字则需加上[/][]let后的表达式只能进行整数运算[/]
B: 使用(())
var=1
((var+=1))
echo $var

输出结果为2注意:
(())的使用方法与let完全相同
C: 使用$[]
var=1
var=$[$var+1]
echo $var

输出结果位2注意:
[]$[]将中括号内的表达式作为数学运算先计算结果再输出[/][]对$[]中的变量进行访问时前面需要加$[/][]$[]支持的运算符与let相同,但也只支持整数运算[/]
D: 使用expr
var=1
var=`expr $var + 1`
echo $var

输出结果为2注意:
[]expr后的表达式个符号间需用空格隔开[/][]expr支持的操作符有: |、&、<、<=、=、!=、>=、>、+、-、、/、%[/*][]expr支持的操作符中所在使用时需用\进行转义的有:|、&、<、<=、>=、>、[/*][]expr同样只支持整数运算[/]
E:使用bc(可以进行浮点数计算)
var=1
var=`echo "$var+1"|bc`
echo $var

输出结果为2介绍:
bc是linux下的一个简单计算器,支持浮点数计算,在命令行下输入bc即进入计算器程序,而我们想在程序中直接进行浮点数计算时,利用一个简单的管道即可解决问题。注意:
[]经我测试bc支持除位操作运算符之外的所有运算符。[/][]bc中要使用scale进行精度设置[/]
浮点数计算实例:
var=3.14
var=`echo "scale=2;$var*3"|bc`
echo $var

输出结果为9.42F:使用awk(可进行浮点数计算)​
var=1
var=`echo "$var 1"|awk '{printf("%g",$1*$2)}'`
echo $var

输出结果为2介绍:
awk是一种文本处理工具,同时也是一种程序设计语言,作为一种程序设计语言,awk支持多种运算,而我们可以利用awk来进行浮点数计算,和上面bc一样,通过一个简单的管道,我们便可在程序中直接调用awk进行浮点数计算。注意:
[]awk支持除微操作运算符之外的所有运算符[/][]awk内置有log、sqr、cos、sin等等函数[/]
浮点数计算实例:
var=3.14
var=`echo "$var 2"|awk '{printf("%g",sin($1/$2))}'`
echo $var

输出结果为1

总结​

终于把所有搜集到的资料看完,最后总结分享给大家,以后再遇到shell计算问题,就可以直接用了! 查看全部
Shell中的赋值和操作默认都是字符串处理,在此记下shell中进行数学运算的几个特殊方法,以后用到的时候可以来看看:


错误方法举例​


A:
 var=1+1
echo $var

输出的结果是1+1,悲剧,呵呵
B:
var=1
var=$var+1
echo $var

输出结果是1+1,依然悲剧,呵呵


正确方法


A: 使用let
var=1
let "var+=1"
echo $var

输出结果为2,这次没有悲剧
注意:
    []经我测试let几乎支持所有的运算符,在网上看到一篇文章说“let不支持++、--和逗号、(、)”,但经我测试自加、自减、以及括号的优先级都得到了很好的支持[/][]方幂运算应使用“”[/][]参数在表达式中直接访问,不必加$[/][]一般情况下算数表达式可以不加双引号,但是若表达式中有bash中的关键字则需加上[/][]let后的表达式只能进行整数运算[/]

B: 使用(())
var=1
((var+=1))
echo $var

输出结果为2
注意:
(())的使用方法与let完全相同
C: 使用$[]
var=1
var=$[$var+1]
echo $var

输出结果位2
注意:
    []$[]将中括号内的表达式作为数学运算先计算结果再输出[/][]对$[]中的变量进行访问时前面需要加$[/][]$[]支持的运算符与let相同,但也只支持整数运算[/]

D: 使用expr
var=1
var=`expr $var + 1`
echo $var

输出结果为2
注意:
    []expr后的表达式个符号间需用空格隔开[/][]expr支持的操作符有: |、&、<、<=、=、!=、>=、>、+、-、、/、%[/*][]expr支持的操作符中所在使用时需用\进行转义的有:|、&、<、<=、>=、>、[/*][]expr同样只支持整数运算[/]

E:使用bc(可以进行浮点数计算)
var=1
var=`echo "$var+1"|bc`
echo $var

输出结果为2
介绍:
bc是linux下的一个简单计算器,支持浮点数计算,在命令行下输入bc即进入计算器程序,而我们想在程序中直接进行浮点数计算时,利用一个简单的管道即可解决问题。
注意:
    []经我测试bc支持除位操作运算符之外的所有运算符。[/][]bc中要使用scale进行精度设置[/]

浮点数计算实例:
var=3.14
var=`echo "scale=2;$var*3"|bc`
echo $var

输出结果为9.42
F:使用awk(可进行浮点数计算)​
var=1
var=`echo "$var 1"|awk '{printf("%g",$1*$2)}'`
echo $var

输出结果为2
介绍:
awk是一种文本处理工具,同时也是一种程序设计语言,作为一种程序设计语言,awk支持多种运算,而我们可以利用awk来进行浮点数计算,和上面bc一样,通过一个简单的管道,我们便可在程序中直接调用awk进行浮点数计算。
注意:
    []awk支持除微操作运算符之外的所有运算符[/][]awk内置有log、sqr、cos、sin等等函数[/]

浮点数计算实例:
var=3.14
var=`echo "$var 2"|awk '{printf("%g",sin($1/$2))}'`
echo $var

输出结果为1


总结​


终于把所有搜集到的资料看完,最后总结分享给大家,以后再遇到shell计算问题,就可以直接用了!

Shell数组详解

开源技术Ansible 发表了文章 • 1 个评论 • 547 次浏览 • 2016-03-21 23:34 • 来自相关话题

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。

数组定义

在Shell中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:array_name=(value1 ... valuen)例如:array_name=(value0 value1 value2 value3)或者array_name=(
value0
value1
value2
value3
)还可以单独定义数组的各个分量:array_name[0]=value0
array_name[1]=value1
array_name[2]=value2可以不使用连续的下标,而且下标的范围没有限制。

读取数组

读取数组元素值的一般格式是:${array_name[index]}例如:result=${array[2]}举个栗子:#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Index: ${IT[0]}"
echo "Second Index: ${IT[1]}"运行脚本,输出:First Index: hadoop
Second Index: cloud用${数组名[下标]} 下标是从0开始  下标是:*或者@ 得到整个数组内容
举个栗子:
[root@workhost ansible]# vim test.sh
#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Method: ${IT[*]}"
echo "Second Method: ${IT[@]}"

[root@workhost ansible]# bash test.sh
First Method: hadoop cloud docker virtual web
Second Method: hadoop cloud docker virtual web

获取数组的长度

# 取得整个数组的长度
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
举个栗子:





删除数组

unset array_name
unset array_name[n]举个栗子:





特殊用法

分片:
[root@workhost ~]$ a=(1 2 3 4 5)
[root@workhost ~]$ echo ${a[@]:0:3}
1 2 3
[root@workhost ~]$ echo ${a[@]:1:4}
2 3 4 5

[root@workhost ~]$ c=(${a[@]:1:4})
[root@workhost ~]$ echo ${#c[@]}
4
[root@workhost ~]$ echo ${c}
2 3 4 5直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用"空格"分开,因此如果加上"()",将得到切片数组,上面例子:c就是一个新数据。
替换:
[root@workhost ~]$ a=(1 2 3 4 5)
[root@workhost ~]$ echo ${a[@]/3/100}
1 2 100 4 5
[root@workhost ~]$ echo ${a[@]}
1 2 3 4 5

[root@workhost ~]$ a=(${a[@]/3/100})
[root@workhost ~]$ echo ${a[@]}
1 2 100 4 5调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,可以看上面例子,重新定义数据。
  查看全部
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。


数组定义


在Shell中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
array_name=(value1 ... valuen)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
可以不使用连续的下标,而且下标的范围没有限制。


读取数组


读取数组元素值的一般格式是:
${array_name[index]}
例如:
result=${array[2]}
举个栗子:
#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Index: ${IT[0]}"
echo "Second Index: ${IT[1]}"
运行脚本,输出:
First Index: hadoop
Second Index: cloud
用${数组名[下标]} 下标是从0开始  下标是:*或者@ 得到整个数组内容
举个栗子:
[root@workhost ansible]# vim test.sh
#!/bin/bash

IT[0]="hadoop"
IT[1]="cloud"
IT[2]="docker"
IT[3]="virtual"
IT[4]="web"
echo "First Method: ${IT[*]}"
echo "Second Method: ${IT[@]}"

[root@workhost ansible]# bash test.sh
First Method: hadoop cloud docker virtual web
Second Method: hadoop cloud docker virtual web


获取数组的长度


# 取得整个数组的长度
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

举个栗子:
len.png


删除数组


unset array_name
unset array_name[n]
举个栗子:
delete_array.png


特殊用法


分片:
[root@workhost ~]$ a=(1 2 3 4 5)
[root@workhost ~]$ echo ${a[@]:0:3}
1 2 3
[root@workhost ~]$ echo ${a[@]:1:4}
2 3 4 5

[root@workhost ~]$ c=(${a[@]:1:4})
[root@workhost ~]$ echo ${#c[@]}
4
[root@workhost ~]$ echo ${c}
2 3 4 5
直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用"空格"分开,因此如果加上"()",将得到切片数组,上面例子:c就是一个新数据。
替换:
[root@workhost ~]$ a=(1 2 3 4 5)    
[root@workhost ~]$ echo ${a[@]/3/100}
1 2 100 4 5
[root@workhost ~]$ echo ${a[@]}
1 2 3 4 5

[root@workhost ~]$ a=(${a[@]/3/100})
[root@workhost ~]$ echo ${a[@]}
1 2 100 4 5
调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,可以看上面例子,重新定义数据。
 

监控Mysql主从同步脚本

开源技术采菊篱下 发表了文章 • 2 个评论 • 632 次浏览 • 2015-11-24 00:02 • 来自相关话题

Shell版本

#!/bin/bash
#Auth: lucky.chen

hosts="192.168.3.9:3305
192.168.3.10:3306
"
for i in $hosts
do
alert=0
host=`echo $i|awk -F':' '{print $1}'`
port=`echo $i|awk -F':' '{print $2}'`
declare -i alert
IO=`mysql -uwrite -P$port -p'write@jkb' -h${host} -e "show slave status\G"|grep Slave_IO_Running: |awk '{print $NF}'`
SQL=`mysql -uwrite -P$port -p'write@jkb' -h${host} -e "show slave status\G"|grep Slave_SQL_Running: |awk '{print $NF}'`
declare -i BEHIN=`mysql -uwrite -P$port -p'write@jkb' -h${host} -e "show slave status\G"|grep Seconds_Behind_Master|awk '{print $NF}'`

if [ $IO != Yes ] ;then
status="${status} \n IO is $IO"
alert=1
fi

if [ $SQL != Yes ] ;then
stauts="${status} \n SQL is $SQL"
alert=1
fi

if [[ $BEHIN -gt 100 ]] ;then
status="${status} \n behind master $BEHIN second"
alert=1
fi


if [[ alert -eq 1 ]] ;then
echo -e "$host : $status"
php /usr/local/bin/sendmail/tongbu.php "$host $status" "$status"
fi

done

python简易版本

#!/usr/bin/env python
# _[i]_coding: utf8_[/i]_
import MySQLdb
from MySQLdb import cursors
import threading

slaveList = [
'ip list'
]
def getSlaveTime(host):
try:
username = 'username'
passwd = 'password'
conn = MySQLdb.connect(user = username, passwd = passwd, host = host, connect_timeout = 5, cursorclass = cursors.DictCursor)
cur = conn.cursor()
cur.execute('''show slave status''')
fallSec = cur.fetchone()['Seconds_Behind_Master']
cur.close()
conn.close()
print host + ' 落后 ' + str(fallSec)
except:
print host + ' 落后 ' + str(10000000)

for host in slaveList:
s = threading.Thread(target = getSlaveTime,args = (host,))
s.start() 查看全部


Shell版本


#!/bin/bash
#Auth: lucky.chen

hosts="192.168.3.9:3305
192.168.3.10:3306
"
for i in $hosts
do
alert=0
host=`echo $i|awk -F':' '{print $1}'`
port=`echo $i|awk -F':' '{print $2}'`
declare -i alert
IO=`mysql -uwrite -P$port -p'write@jkb' -h${host} -e "show slave status\G"|grep Slave_IO_Running: |awk '{print $NF}'`
SQL=`mysql -uwrite -P$port -p'write@jkb' -h${host} -e "show slave status\G"|grep Slave_SQL_Running: |awk '{print $NF}'`
declare -i BEHIN=`mysql -uwrite -P$port -p'write@jkb' -h${host} -e "show slave status\G"|grep Seconds_Behind_Master|awk '{print $NF}'`

if [ $IO != Yes ] ;then
status="${status} \n IO is $IO"
alert=1
fi

if [ $SQL != Yes ] ;then
stauts="${status} \n SQL is $SQL"
alert=1
fi

if [[ $BEHIN -gt 100 ]] ;then
status="${status} \n behind master $BEHIN second"
alert=1
fi


if [[ alert -eq 1 ]] ;then
echo -e "$host : $status"
php /usr/local/bin/sendmail/tongbu.php "$host $status" "$status"
fi

done


python简易版本


#!/usr/bin/env python
# _[i]_coding: utf8_[/i]_
import MySQLdb
from MySQLdb import cursors
import threading

slaveList = [
'ip list'
]
def getSlaveTime(host):
try:
username = 'username'
passwd = 'password'
conn = MySQLdb.connect(user = username, passwd = passwd, host = host, connect_timeout = 5, cursorclass = cursors.DictCursor)
cur = conn.cursor()
cur.execute('''show slave status''')
fallSec = cur.fetchone()['Seconds_Behind_Master']
cur.close()
conn.close()
print host + ' 落后 ' + str(fallSec)
except:
print host + ' 落后 ' + str(10000000)

for host in slaveList:
s = threading.Thread(target = getSlaveTime,args = (host,))
s.start()

shell交互批量修改主机名

开源技术Ansible 发表了文章 • 0 个评论 • 792 次浏览 • 2015-11-15 12:51 • 来自相关话题

场景

有时候我们有批量修改主机名和同步hosts文件到多台主机的需求,例如新上了一批服务器等,可能主机名称上并不能满足你的命名规则或规范,但如果一台台去更改可能就太慢又无聊,所以shell脚本绝对是你的最佳选择。

需求分析

[]ssh公钥拷贝,提供无密码管理。[/][]批量同步hosts文件到多台主机。[/][]批量修改主机名。[/]

实现

首先编辑一份用于同步到多台主机的hosts文件# vi /etc/hosts

192.168.0.1 server1
192.168.0.2 server2
192.168.0.3 server3
192.168.0.4 server4
192.168.0.5 server5
192.168.0.6 server6
192.168.0.7 server7
192.168.0.8 server8
192.168.0.9 server9
192.168.0.10 server10然后编辑shell脚本:# vi changename.sh

#!/bin/bash
# This is a shell script to change hostname

export PATH=$PATH
export USER=root
export SNAMEPRE=server
export PASSWD=test01 #定义密码
for i in {1..10};
do /usr/bin/expect << EOF [size=16]这里用到了expect完成了确认yes和密码输入交互[/size]
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $USER@$SNAMEPRE$i
expect {
"(yes/no)?" {send "yes\r";exp_continue}
"password:" {send "$PASSWD\r"}
}
interact
expect eof
EOF
ssh $USER@$SNAMEPRE$i "sed -i s/^HOST.*/HOSTNAME=$SNAMEPRE$i/ /etc/sysconfig/network";
scp /etc/hosts $USER@$SNAMEPRE$i:/etc/hosts;
done;这里用到了expect完成自动交互确认和密码输入。

Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect的作者Don Libes在1990年 开始编写Expect时对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。使用它系统管理员 的可以创建脚本用来实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)得到输入,一般来说这些输入都需要手工输入进行的。更多Expect信息请查看站点  http://expect.sourceforge.net/
这样一个简单的脚本就帮你完成3件事,拷贝公钥、修改主机名、同步hosts文件。
 
如果使用ansible会更简单! 查看全部


场景


有时候我们有批量修改主机名和同步hosts文件到多台主机的需求,例如新上了一批服务器等,可能主机名称上并不能满足你的命名规则或规范,但如果一台台去更改可能就太慢又无聊,所以shell脚本绝对是你的最佳选择。


需求分析


    []ssh公钥拷贝,提供无密码管理。[/][]批量同步hosts文件到多台主机。[/][]批量修改主机名。[/]


实现


首先编辑一份用于同步到多台主机的hosts文件
# vi /etc/hosts

192.168.0.1 server1
192.168.0.2 server2
192.168.0.3 server3
192.168.0.4 server4
192.168.0.5 server5
192.168.0.6 server6
192.168.0.7 server7
192.168.0.8 server8
192.168.0.9 server9
192.168.0.10 server10
然后编辑shell脚本:
# vi changename.sh

#!/bin/bash
# This is a shell script to change hostname

export PATH=$PATH
export USER=root
export SNAMEPRE=server
export PASSWD=test01 #定义密码
for i in {1..10};
do /usr/bin/expect << EOF [size=16]这里用到了expect完成了确认yes和密码输入交互[/size]
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $USER@$SNAMEPRE$i
expect {
"(yes/no)?" {send "yes\r";exp_continue}
"password:" {send "$PASSWD\r"}
}
interact
expect eof
EOF
ssh $USER@$SNAMEPRE$i "sed -i s/^HOST.*/HOSTNAME=$SNAMEPRE$i/ /etc/sysconfig/network";
scp /etc/hosts $USER@$SNAMEPRE$i:/etc/hosts;
done;
这里用到了expect完成自动交互确认和密码输入。

Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect的作者Don Libes在1990年 开始编写Expect时对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。使用它系统管理员 的可以创建脚本用来实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)得到输入,一般来说这些输入都需要手工输入进行的。
更多Expect信息请查看站点  http://expect.sourceforge.net/
这样一个简单的脚本就帮你完成3件事,拷贝公钥、修改主机名、同步hosts文件。
 
如果使用ansible会更简单!

监控IO脚本

开源技术koyo 发表了文章 • 0 个评论 • 522 次浏览 • 2015-11-05 18:04 • 来自相关话题

#!/bin/sh

/etc/init.d/syslog stop

echo 1 > /proc/sys/vm/block_dump

sleep 60

dmesg | awk '/(READ|WRITE|dirtied)/ {process[$1]++} END {for (x in process) \

print process[x],x}' |sort -nr |awk '{print $2 " " $1}' | \

head -n 10

echo 0 > /proc/sys/vm/block_dump

/etc/init.d/syslog start 查看全部
#!/bin/sh

/etc/init.d/syslog stop

echo 1 > /proc/sys/vm/block_dump

sleep 60

dmesg | awk '/(READ|WRITE|dirtied)/ {process[$1]++} END {for (x in process) \

print process[x],x}' |sort -nr |awk '{print $2 " " $1}' | \

head -n 10

echo 0 > /proc/sys/vm/block_dump

/etc/init.d/syslog start
Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。