scripts-杂项

等不做运维了,估计都不知道自己写过什么,随时间遗忘吧。

mic

登录提示

cd
cat <<\EOF> .tips 
tips='su - aws-ssl 亚马逊
bash xxxx.sh同步
'
echo "$tips"
EOF


cat <<\EOF>> .bash_profile
. .tips
EOF

别名

cat <<\EOF >> ~/.bashrc
# 扫描新加的磁盘
alias scandisk='echo - - - >/sys/class/scsi_host/host0/scan;echo - - - >/sys/class/scsi_host/host1/scan;echo - - - > /sys/class/scsi_host/host2/scan'
EOF

流量控制 ssctl

脚本功能:

  1. 一键添加删除端口(用户)
  2. 限制每月流量
  3. 超过流量端口(用户)自动限制
  4. 月初自动清空限制流量使用归零

注意事项

  1. 该脚本只支持python版ss
  2. 需要保证ss的环境变量配置正确,即直接输入ssserver命令可执行
  3. 配置文件需要按照帮助中的格式配置
  4. 直接执行可输出帮助信息

使用方法

  1. 写配置文件。下载脚本后直接执行一下可获取配置文件模板,把配置文件放在/etc/shadowsocks.json
  2. ssctl.sh addport [端口号] [流量数(G)] [备注信息] 添加端口
  3. ssctl.sh delport [端口号] 删除端口

脚本内容

cat <<\EOF >> ssctl.sh
#!/bin/bash
source /etc/profile

VERSION=1.1.5

helpmsg() {
    echo "Version $VERSION"
    echo 'usage: ssctl.sh [OPTION]...'
    echo
    echo 'Options:'
    echo '  server       Ssserver contral'
    echo '      start        Start ssserver by /etc/shadowsocks.json'
    echo '      stop         Stop ssserver'
    echo '      restart      Restart ssserver'
    echo '  addport      Usage:addport <PORT> <data> [description] Add a new port for user'
    echo '  delport      Usage:delport <PORT> Delete port'
    echo '  drop         Iptables contral'
    echo '      add          Useage:add <PORT> Add port to iptables DROP list'
    echo '      del          Useage:del <PORT|all> Delete a port from iptables DROP list or delete all'
    echo '  portdata     Usage:portdata <PORT> check data usage'
    echo 
    confex
}

confex() {
    echo '#####The configuration file format example#####'
    echo 'Configuration file path /etc/shadowsocks.json' 
    echo '{'
    echo '    "server":"0.0.0.0",'
    echo '    "local_address":"127.0.0.1",'
    echo '    "local_port":1080,'
    echo '    "port_password":{'
    echo '        "10001":"password1",'
    echo '        "10002":"password2",'
    echo '        "10003":"password3"'
    echo '    },'
    echo '    "timeout":300,'
    echo '    "method":"aes-256-cfb",'
    echo '    "fast_open": false,'
    echo '    "workers":1'
    echo '}'
    echo
}

confcheck() {
    CONF=`grep 'port_password' /etc/shadowsocks.json`
    if [ -z "$CONF" ];then
        echo
        echo '#####Error in configuration file format#####'
        echo '#####   Please refer to the example    #####'
        echo 'Configuration file path /etc/shadowsocks.json' 
        echo 
        confex
        exit
    fi
}

croncheck() {
    CRONROOT=/var/spool/cron/root
    DIR=`cd "$(dirname "$0")";pwd`
    NAME=`basename $0`
    PWDPATH="$DIR/$NAME"
    CHECK=`grep "$PWDPATH check" $CRONROOT`
    CLEAN1=`grep "$PWDPATH drop del all" $CRONROOT`
    CLEAN2=`grep '/sbin/iptables -Z' $CRONROOT`
    [ -z "$CHECK" ] && echo "* * * * * /bin/bash $PWDPATH check &> /dev/null" >> $CRONROOT
    [ -z "$CLEAN1" ] && echo "10 0 1 * * /bin/bash $PWDPATH drop del all &> /dev/null" >> $CRONROOT
    [ -z "$CLEAN2" ] && echo "0 0 1 * * /sbin/iptables -Z &> /dev/null" >> $CRONROOT
}

server() {
    case $1 in
    start)
        ssserver --user nobody -c /etc/shadowsocks.json -d start
        ;;
    stop)
        ssserver -d stop
        ;;
    restart)
        ssserver -d stop
    for i in {1..20};do
        echo -n '='
            sleep 0.1
    done
    echo
        ssserver --user nobody -c /etc/shadowsocks.json -d start
        ;;
    *)
    helpmsg
        ;;
    esac
}

addport() {
    [[ ! $1 =~ [0-9]+ ]] && echo 'Port wrong' && exit
    [[ ! $2 =~ [0-9]+ ]] && echo 'Data wrong' && exit
    PORT=`grep $1 /etc/shadowsocks.json`
    [ -n "$PORT" ] && echo 'This port already exists' && exit
    PASSWD=`cat /dev/urandom | tr -dc '0-9a-zA-Z' | head -c 20`
    iptables -A OUTPUT -p tcp --sport $1
    iptables -A OUTPUT -p udp --sport $1
    sed -ri "/port_password/a\        \"$1\"\:\"$PASSWD\"," /etc/shadowsocks.json
    echo "$1 $2 $3" >> /etc/ssuser.conf
    server restart
    echo "Port:$1 Password:$PASSWD"
}

delport() {
    [[ ! $1 =~ [0-9]+ ]] && echo 'Port wrong' && exit
    NUM=`iptables -vnL OUTPUT --line-numbers | grep "spt:$1" | awk '{print $1}'`
    [ -z "$NUM" ] && echo 'Can not find this port' && exit
    iptables -D OUTPUT -p tcp --sport $1
    iptables -D OUTPUT -p udp --sport $1
    sed -ri "/$1/d" /etc/shadowsocks.json
    sed -ri "/$1/d" /etc/ssuser.conf
    server restart
    echo "Delete $1 successd"
}

drop() {
    case $1 in
    del)
        if [ "$2" = "all" ];then
            DROPNUM=`iptables -vnL INPUT --line-numbers | grep "DROP" | grep -E 'dpt:[0-9]+' | awk '{print $1}'`
            for i in $DROPNUM;do
                NUM=`iptables -vnL INPUT --line-numbers | grep "DROP" | grep -E 'dpt:[0-9]+' | head -n1 | awk '{print $1}'`
                iptables -D INPUT $NUM
            done
        else
            [[ ! $2 =~ [0-9]+ ]] && echo 'Port wrong' && exit
            iptables -D INPUT -p tcp --dport $2 -j DROP
            iptables -D INPUT -p udp --dport $2 -j DROP
        fi
        ;;
    add)
        [[ ! $2 =~ [0-9]+ ]] && echo 'Port wrong' && exit
        iptables -A INPUT -p tcp --dport $2 -j DROP
        iptables -A INPUT -p udp --dport $2 -j DROP
        ;;
    *)
    helpmsg
        ;;
    esac
}

check() {
    PORT=`awk '{print $1}' /etc/ssuser.conf`
    for i in $PORT;do
        DATACONF=`grep "$i" /etc/ssuser.conf | awk '{print $2}'`
        DATANUM=$[${DATACONF}*1024*1024*1024]
        DATA=`iptables -vnL OUTPUT -x | grep "spt:$i" | awk '{print $2}'`
        for j in $DATA;do
            let DATANOW+=$j
        done
        if [ $DATANOW -gt $DATANUM ];then
            CHK=`iptables -vnL | grep "dpt:${i}"`
            [ -z "$CHK" ] && drop add $i
        fi
        unset DATANOW
    done
}

portdata() {
    CHK=`grep "$1" /etc/ssuser.conf`
    [ -z "$CHK" ] && echo 'Can not find this port' && exit
    DATA=`iptables -vnL OUTPUT -x | grep "spt:$1" | awk '{print $2}'`
    for i in $DATA;do
        let DATANOW+=$i
    done
    PORTDATA=`echo $DATANOW | awk '{printf "%.3f\r",$1/1024/1024/1024}'`
    DATACONF=`grep "$1" /etc/ssuser.conf | awk '{print $2}'`
    echo "Port:$1"
    echo "Total:${DATACONF}"
    echo "Used:${PORTDATA}"
}

main() {
    confcheck
    croncheck
    case $1 in
    addport)
        addport $2 $3 $4
    ;;
    delport)
        delport $2
    ;;
    drop)
        drop $2 $3
    ;;
    server)
        server $2
    ;;
    check)
        check
    ;;
    portdata)
        portdata $2
    ;;
    *)
    helpmsg
    ;;
    esac
}

main $1 $2 $3 $4

EOF

cpu-使用高找到进程

cat <<\EOF> check-cpu.sh 
#!/usr/bin/env bash
#

break_num=0
>/tmp/cpu-high.log

while true; do

sleep 5
status=$(top -c -bn 1 |sed -n '/%Cpu/p'|awk '{if($8<20){print 1}else{print 0}}')
[ $status -eq 1 ] && date +'%F %T' >>/tmp/cpu-high.log && top -c -bn 1|sed -n '2,15p' >>/tmp/cpu-high.log && let break_num+=1 && echo "==============" >>/tmp/cpu-high.log
[ $break_num -eq 3000 ] && break
done
EOF

disk磁盘检查

cat <<\EOF> disk_check.sh
#!/bin/bash
export PATH=$PATH
DISK_PERCENT=`df | awk '/alidata/{print $5}' | grep -o '[0-9]*'`
i=0
LINE=2
while [ "$DISK_PERCENT" -ge 90 ];do
    FILE_NAME=/alidata/logs/server/`ls -lrt /alidata/logs/server | sed -rn "${LINE}p" | awk '{print $9}'`
    [[ ! "$FILE_NAME" =~ "_" ]] && let LINE+=1 && continue
    /bin/rm -f "$FILE_NAME"
    DISK_PERCENT=`df | awk '/alidata/{print $5}' | grep -o '[0-9]*'`
    let i+=1
    sleep 0.1
    [ $i -ge 1000 ] && exit
done
unset DISK_PERCENT FILE_NAME i LINE
exit
EOF

expect_分发key

#!/bin/bash
# function: remote dis ssh key.
# version:1.0
################################################

. /etc/init.d/functions
file="$1"
remote_dir="$2"
if [[ $# -ne 2 ]];then
    echo  "usage:$0 argv2"
    echo "must have one argvs"
    exit
fi
function KNOWN_HOST_REBUILD()
{
    #确保本机存在known_hosts列表
    [ ! -e ~/.ssh/known_hosts ] && mkdir -p ~/.ssh/ && touch ~/.ssh/known_hosts
    local i=$1
    sed -i "/^${i} /d" ~/.ssh/known_hosts
    expect -c "
    spawn /usr/bin/ssh operator1@${i} echo ok;
    expect \"*yes/no)?\";
    send \"yes\r\";
    expect eof " >/dev/null 2>&1
    return 0
    [[ $? -ne 0 ]] && echo "$i know host rebuild fail,maybe the server connect error"
}
function PASS_PASSWD()
{
    ip=$1
    expect -c "
    set timeout -1
    spawn ssh-copy-id -i id_dsa oldboy@$ip
    expect \"*password:\"
    send \"oldboy123\r\"
    expect eof" >/dev/null 2>&1
}
function FENFA_id_dsa()
{
    for ip in `awk '/^[^#]/{print $1}' all_client.txt`
    do
        KNOWN_HOST_REBUILD $ip
        PASS_PASSWD $ip
        if [[ $? -eq 0 ]];then
            action "$ip send id_dsa is successful" /bin/true
        else
            action "$ip send id_dsa is failed copied" /bin/false
        fi
    done
}
function FENFA_config()
{
    for ip in `awk '/^[^#]/{print $1}' all_client.txt`
    do
        port=$(grep $ip all_client.txt|awk '{print $2}')
        scp -P${port} -r -p ${file} oldboy@${ip}:~ >/dev/null 2>&1 && \
        ssh -p${port} -t oldboy@$ip sudo rsync ~/`basename ${file}` $remote_dir >/dev/null 2>&1
        if [[ $? -eq 0 ]];then
            action "$ip send $file is successful!!" /bin/true
        else
            action "$ip send $file is failed!!" /bin/false
        fi
    done
}
FENFA_id_dsa
FENFA_config

other

cat<<\EOF> copy_id.exp
#!/usr/bin/expect
if { $argc != 2 } {   
 send_user "usage: expect fenfa_sshkey.exp file host\n"   
 exit   
}

#define var
set file [lindex $argv 0]
set host [lindex $argv 1]
set password "Word13205"

spawn ssh-copy-id -i  $file "-p 10022 operator1@$host"
expect {
    "yes/no"    {send "yes\r";exp_continue}
    "*password" {send "$password\r"}
}
expect eof

exit -onexit {
  send_user "good bye !\n"
}
EOF


#配置ssh密钥登录

#expect脚本
cat <<\EOF> .copy-key.exp
#!/usr/bin/expect -f
set ip [lindex $argv 0]
set user [lindex $argv 1]
set passwd [lindex $argv 2]

set timeout 10

spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $user@$ip

expect {
    "*password:" {send "$passwd\r"}
    "*yes/no*" {send "yes\r"}
}

expect off
EOF

shell调用expect脚本
cat <<\EOF> fenfa.sh
#!/bin/bash
while read id;do
    ip=`echo $id | awk '{print $1}'`
    user=`echo $id | awk '{print $2}'`
    passwd=`echo $id | awk '{print $3}'`
    ./copy-key.exp $ip $user $passwd
done <host.list
EOF

#host.list格式
192.168.60.152 root root
192.168.60.155 root root
192.168.60.156 root root

日志

日志切割

Linux Shell实现仅保留最新的文件|删除最旧的文件|Bash

ls -t | awk ‘{if(NR>16){print $0}}’ |xargs rm -f
[operator1@nginx01 ~]$ sudo su -
[root@nginx01 ~]# crontab -l
#00  00  *  *  *  /bin/bash  /environment/nginx/sbin/cutlognginx.sh  >/dev/null 2>&1
00 00 * * * /bin/bash /ops/nginx_qiege.sh >/dev/null 2>&1
00 00 * * * /bin/bash /ops/haproxy_qiege.sh >/dev/null 2>&1
*/1 * * * * /bin/bash /ops/disk_log.sh >/dev/null 2>&1

nginx日志切割

[root@nginx01 ~]# vim /ops/nginx_qiege.sh
#!/bin/bash
#logs_path=/environment/nginx/logs/
logs_path=/var/www/logs
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
mv ${logs_path}/www.hdzuoye.com8080.log ${logs_path}/log_backup/www.hdzuoye.com8080_${YESTERDAY}.log
kill -USR1 $(cat /environment/nginx/logs/nginx.pid)

haproxy日志切割

[root@nginx01 ~]# vim /ops/haproxy_qiege.sh
#!/bin/bash
#logs_path=/environment/nginx/logs/
logs_path=/var/www/logs
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
cp -rf  /var/www/haproxy/haproxy.log ${logs_path}/haproxy/haproxy_access_${YESTERDAY}.log
>/var/www/haproxy/haproxy.log

logrote_nginx

/mnt/logs/nginx/*.log {
        daily   #按日轮循
        copytruncate
        missingok
        dateext
        rotate 52
        compress
        delaycompress
        notifempty
        #create 640 nginx adm
        sharedscripts
        postrotate
                [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
        endscript
}

shell进度条

[root@agent01 ~]# sh c.sh
[####################################################################################################][100%]|
[root@agent01 ~]# cat c.sh
#!/bin/bash
i=0;
str=""
arr=("|" "/" "-" "\\")
while [ $i -le 100 ]
do
  let index=i%4
  let indexcolor=i%8
  let color=30+indexcolor
  printf "\e[0;$color;1m[%-100s][%d%%]%c\r\e[0m" "$str" "$i" "${arr[$index]}"
  usleep 50000
  let i++
  #str+='█'
  str+='#'
done
printf "\n"

删除文件

批量删除子目录下的文件,保留指定数量的最新文件

方法1

#!/bin/bash
#保留文件数
ReservedNum=2
#要删除文件的,父级目录
FileDir=/usr/docker/springCloud/project/
 
#循环子目录列表
for element in `ls $FileDir`
do
    # 拼接成完成目录 (父目录路径/子目录名)
    dir_or_file=$FileDir$element
    # 获取子目录下的指定文件格式的总数量
    FileNum=$(ls -l $dir_or_file | grep 'keda-' |wc -l)
    # 输出 删除前的 指定格式的文件数量
    echo  $element "jar num:" $FileNum
    # 如果 数量大于保留数量,那就循环删除 文件
    while(( $FileNum > $ReservedNum))
    do
       OldFile=$(ls -rt $dir_or_file | grep 'keda-'| head -1)
       echo  $element "Delete jar:"$OldFile
       rm -rf $dir_or_file/$OldFile
       let "FileNum--"
    done
done
 
# 删除完后,再循环输出一下 每个子目录下的文件数量
for element in `ls $FileDir`
do
    dir_or_file=$FileDir$element
    FileNum=$(ls -l $dir_or_file | grep 'keda-' |wc -l)
    echo  $element "jar num:" $FileNum

方法2

ls -t | awk '{if(NR>16){print $0}}'  |xargs rm -f

tomcat故障重启

[handler@user06 alidata]$ cat ~/Monitor_tomcat_hdserver_url.sh
#!/bin/bash
TomcatCache=/usr/local/tomcat_hd-server/work
TomcatPID=$(/bin/ps -ef|grep tomcat_hd-server|grep -v grep|grep start|awk '{print $2}')
HostName=$(hostname)
lockfile="/usr/local/tomcat_hd-server/lockfile"


check_lock() {
    if [  -f "$1" ]; then
        exit 1
    fi
}

multi_check() {
    UP=0
    DOWN=0
    while [ $UP -lt 5 -a $DOWN -lt 5 ];do
        local num=$(curl -I -m 5 -s -w "%{http_code}\n" -o /dev/null $URL | grep -E  "200|301|302" |wc -l)
        if [ $num -eq 1 ];then
            let UP+=1
            echo "$1: $URL 连接成功 ${UP}"
        else
            let DOWN+=1
            echo "$1: $URL 连接失败 ${DOWN}"
        fi
        /bin/sleep 1
    done
    if [ $UP -eq 5 ];then
        exit 0
    fi
    if [ $DOWN -eq 5 ];then
        echo "$1: tomcat重启..."
    fi
}

checkurl(){
    check_lock $lockfile
    if [ -n "$TomcatPID" ];then
        local num=$(curl -I -m 5 -s -w "%{http_code}\n" -o /dev/null $URL | grep -E  "200|301|302" |wc -l)
        if [ $num -eq 1 ];then #<==采用获取状态码,并转为数字的方式判断,如果301认为正确也可以加上egrep过滤。
            #echo "$HostName: $URL is ok"
            exit 0
        else
           echo "----------[$(date +'%F %H:%M:%S')]----------"
           echo "$HostName: $URL is error, waiting do more test..."
           multi_check $HostName
           kill -9 $TomcatPID &> /dev/null
           sleep 3
           /bin/mv $TomcatCache /tmp/
           /etc/init.d/tomcat_hd-server start
             echo "$HostName: tomcat_hd-server restart at $(date +%F-%T)"
        fi
    else
        echo "----------[$(date +'%F %H:%M:%S')]----------"
        echo "$HostName: tomcat 进程不存在, 启动tomcat..."
        /bin/mv $TomcatCache /tmp/
        /etc/init.d/tomcat_hd-server start
    fi
}

URL_USER="http://localhost:8090/hd-server/advertusement/getOptionalInfo.do"
URL_BOOK="http://localhost:8090/hd-server/advertusement/getOptionalInfo.do"
URL_LEYUAN="http://localhost:8090/hd-server/advertusement/getOptionalInfo.do"
URL_OTHER="http://localhost:8090/hd-server/advertusement/getOptionalInfo.do"
URL_ADVERT="http://localhost:8080/hdzuoye_advertise/advertise/getAdvertiseHideTime.do"
case $1 in
    user)
        URL=${URL_USER};;
    book)
        URL=${URL_BOOK};;
    leyuan)
        URL=${URL_LEYUAN};;
    other)
        URL=${URL_OTHER};;
    advert)
        URL=${URL_ADVERT};;
    --help)
        echo "comand {user|book|leyuan|other}"
        exit 1;;
    *)
        pc_name=$(sed -rn "/$(/usr/sbin/ifconfig eth0 | sed -n '/inet /p'| awk '{print $2}')/s@[[:digit:]\.]+[[:space:]]+([[:alpha:]_-]+).*@\1@gp" /etc/hosts)
        if [ "${pc_name}" == "user" ]; then
            URL=${URL_USER}
        elif [ "${pc_name}" == "book" ]; then
            URL=${URL_BOOK}
        elif [ "${pc_name}" == "leyuan" ]; then
            URL=${URL_LEYUAN}
        elif [ "${pc_name}" == "other" ]; then
            URL=${URL_OTHER}
        elif [ "${pc_name}" == "advert" ]; then
            URL=${URL_ADVERT}
        fi

esac

checkurl