3.32. 百宝箱脚本

3.32.1. Shell 实践、常用脚本进阶

参考文献 https://www.cnblogs.com/xiangsikai/p/8289899.html

3.32.2. Shell 脚本进阶2

参考文献 https://www.cnblogs.com/xiangsikai/p/8929807.html

3.32.3. Shell 实践、常用脚本

参考文献 https://www.cnblogs.com/xiangsikai/p/8289746.html

3.32.4. 备份所有docker镜像

mkdir -p images && cd images
for image in `docker images | grep -v REPOSITORY | awk '{print $1":"$2}'`; do
    echo "saving the image of ${image}"
    docker save ${image} >  ${image////-}.tar
    echo -e "finished saving the image of \033[32m ${image} \033[0m"
done

3.32.5. 批量加载镜像

for image in `ls *.tar`; do
    echo "loading the image of ${image}"
    docker load < ${image}
    echo -e "finished loading the image of \033[32m ${image} \033[0m"
done

3.32.6. 批量杀死僵尸进程

ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9

3.32.7. nginx启动脚本示例

#!/bin/sh

# source function library
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

RETVAL=0
prog="nginx"

nginxDir=/usr/local/nginx
nginxd=$nginxDir/sbin/nginx
nginxConf=$nginxDir/conf/nginx.conf
nginxPid=$nginxDir/nginx.pid

nginx_check()
{
    if [[ -e $nginxPid ]]; then
        ps aux |grep -v grep |grep -q nginx
        if  (( $? == 0 )); then
            echo "$prog already running..."
            exit 1
        else
            rm -rf $nginxPid &> /dev/null
        fi
    fi
}

start()
{
    nginx_check
    if (( $? != 0 )); then
        true
    else
        echo -n $"Starting $prog:"
        daemon $nginxd -c $nginxConf
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
        return $RETVAL
    fi
}

stop()
{
    echo -n $"Stopping $prog:"
    killproc $nginxd
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx $nginxPid
}

reload()
{
    echo -n $"Reloading $prog:"
    killproc $nginxd -HUP
    RETVAL=$?
    echo
}

monitor()
{
    status $prog &> /dev/null
    if (( $? == 0 )); then
        RETVAL=0
    else
        RETVAL=7
    fi
}

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                start
                ;;
        reload)
                reload
                ;;
        status)
                status $prog
                RETVAL=$?
                ;;
        monitor)
                monitor
                ;;
        *)
                echo $"Usage: $0 {start|stop|restart|reload|status|monitor}"
                RETVAL=1
esac
exit $RETVA

3.32.8. Spring Boot启动脚本

#!/bin/bash

SpringBoot=$2

if [ "$1" = "" ];
then
    echo -e "\033[0;31m 未输入操作名 \033[0m  \033[0;34m {start|stop|restart|status} \033[0m"
    exit 1
fi

if [ "$SpringBoot" = "" ];
then
    echo -e "\033[0;31m 未输入应用名 \033[0m"
    exit 1
fi

function start()
{
    count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
    if [ $count != 0 ];then
        echo "$SpringBoot is running..."
    else
        echo "Start $SpringBoot success..."
        nohup java -jar $SpringBoot > /dev/null 2>&1 &
    fi
}

function stop()
{
    echo "Stop $SpringBoot"
    boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
    count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`

    if [ $count != 0 ];then
        kill $boot_id
        count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`

        boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
        kill -9 $boot_id
    fi
}

function restart()
{
    stop
    sleep 2
    start
}

function status()
{
    count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
    if [ $count != 0 ];then
        echo "$SpringBoot is running..."
    else
        echo "$SpringBoot is not running..."
    fi
}

case $1 in
    start)
    start;;
    stop)
    stop;;
    restart)
    restart;;
    status)
    status;;
    *)

    echo -e "\033[0;31m Usage: \033[0m  \033[0;34m sh  $0  {start|stop|restart|status}  {SpringBootJarName} \033[0m
\033[0;31m Example: \033[0m
      \033[0;33m sh  $0  start esmart-test.jar \033[0m"
esac

3.32.9. 安装nginx脚本

#!/bin/bash
#脚本功能描述(Description):一键源码安装Nginx软件包

#定义不同的颜色属性
setcolor_failure="echo -en \\033[91m"
setcolor_success="echo -ne \\033[32m"
setcolor_normal="echo -e \\033[0m"

#判断是否以管理员身份执行脚本
if [[ $UID -ne 0 ]];then
    $setcolor_failure
    echo -n "请以管理员身份运行该脚本."
    $setcolor_normal
    exit
fi

#判断系统中是否存在wget这个下载工具
#wget使用-c选项可以开启断点续传功能
if rpm --quiet -q wget ;then
    wget -c http://nginx.org/download/nginx-1.14.0.tar.gz
else
    $setcolor_failure
    echo -n "未找到wget,请先安装该软件."
    $setcolor_normal
    exit
fi

#如果没有nginx账户,则脚本自动创建该账户
if ! id nginx &>/dev/null ;then
    adduser -s /sbin/nologin nginx
fi

#测试是否存在正确的源码包软件
if [[ ! -f nginx-1.14.0.tar.gz ]];then
    $setcolor_failure
    echo -n "未找到nginx源码包,请先正确下载该软件再试..."
    $setcolor_normal
    exit
else
#源码编译安装前,先安装相关依赖包
#gcc:C语言编译器|pcre-devel:Perl兼容的正则表达式库
#zlib-devel:gzip压缩库|openssl-devel:Openssl加密库
    yum -y install gcc pcre-devel zlib-devel openssl-devel
    clear
    $setcolor_success
    echo -n "接下来,需要花费几分钟时间源码编译安装nginx..."
    $setcolor_normal
    sleep 6
    tar -xf nginx-1.14.0.tar.gz
#源码编译安装nginx,指定账户和组,指定安装路径,开启需要的模块,禁用不需要的模块
    cd nginx-1.14.0/
    ./configure \
     --user=nginx \
     --group=nginx \
     --prefix=/data/server/nginx \
     --with-stream \
     --with-http_ssl_module \
     --with-http_stub_status_module \
     --without-http_autoindex_module \
     --without-http_ssi_module
     make
     make install
fi
if [[ -x /data/server/nginx/sbin/nginx ]];then
    clear
    $setcolor_success
    echo -n "一键部署nginx已经完成!"
    $setcolor_normal
fi

3.32.10. 函数输出帮助信息

#!/bin/bash
#功能描述(Description):使用函数输出帮助信息.

function print_usage() {
    cat << EOF
Usage: --help | -h
  Print help information for script.
Usage: --memory | -m
  Monitor memory information.
Usage: --network | -n
  Monitor network interface information.
EOF
}

case $1 in
--memory|-m)
    free;;
--network|-n)
    ip -s link;;
--help|-h)
    print_usage;;
*)
    print_usage;;
esac

3.32.11. 设置锁文件防止脚本重复执行

#!/bin/bash
#功能描述(Description):通过设置锁文件防止脚本重复执行.

#使用Ctrl+C中断脚本时,删除锁文件.
trap 'rm -rf /tmp/lockfile;exit' HUP INT

#检查是否存在锁文件,没有锁文件就执行backup备份函数,如果有锁文件脚本则脚本直接退出.
lock_check(){
    if (set -C; :> /tmp/lockfile) 2>/dev/null ;then
        backup
    else
        echo -e "\033[91mWarning:其他用户在执行该脚本.\033[0m"
        exit 66
    fi
}

#执行备份前创建所文件,然后执行备份数据库的操作,备份完成后删除锁文件.
#sleep 10实验测试时使用,为了防止小数据库备份太快,无法验证重复执行脚本的效果.
backup(){
    touch /tmp/lockfile
    mysqldump --all-database > /var/log/mysql-$(date +%Y%m%d).bak
    sleep 10
    rm -rf /tmp/lockfile
}

lock_check
backup

3.32.12. Python颜色打印

#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/1 17:57
# filename: ColorPrint.py
import sys


class ColorPrint(object):
    def __init__(self, color, msg):
        self.color = color
        self.msg = msg
        self.cPrint(self.color, self.msg)

    def cPrint(self, color, msg):
        colors = {
            'black': '\033[30m%s\033[0m',
            'red': '\033[31m%s\033[0m',
            'green': '\033[32m%s\033[0m',
            'yellow': '\033[33m%s\033[0m',
            'blue': '\033[34m%s\033[0m',
            'white': '\033[37m%\033[0m'}
        if color in colors.keys():
            message = colors[color] % msg
            print(message)


if __name__ == '__main__':
    # cp = ColorPrint(sys.argv[1], sys.argv[2])
    cp = ColorPrint("red", "I am red color")
    cp2 = ColorPrint("green", "I am red green")
    cp3 = ColorPrint("yellow", "I am red yellow")
    cp4 = ColorPrint("blue", "I am red blue")

3.32.13. 实用脚本

python 爬虫

#/usr/bin/env python

import requests
from bs4 import BeautifulSoup
import pprint
import json
import os


kebie = {
"huxineike":3,
"yingyangke":4
}

for key, value in kebie.items():
    # 下载html页面
    def download_all_htmls():
        htmls = []
        headers = {'User-Agent': 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'}
        for idx in range(value):
            url = f"https://jbk.39.net/bw/{key}_t1_p{idx+1}/"
            #print("craw html:", url)
            r = requests.get(url,headers=headers)
            if r.status_code != 200:
                raise Exception("error")
            htmls.append(r.text)
        return htmls
    htmls = download_all_htmls()
    # 解析html数据
    def parse_single_html(html_doc):
        soup = BeautifulSoup(html_doc, 'html.parser')
        links = soup.body.find_all('p','result_item_top_l')
        datas = []
        for link in links:
            link_node = (
                link
                .find("a")
            )
            title = link_node["title"]
            link = link_node["href"]
            datas.append(
                {"title":title, "link":link}
            )
        return datas
# 执行所有的HTML页面的解析
    all_datas = []
    for html_doc in htmls:
        all_datas.extend(parse_single_html(html_doc))
    pprint.pprint(all_datas)

python循环接口下载图片

# /usr/bin/env python
# -- coding:UTF-8 --

import requests
import json
import os


# 定义调用的url
# 登录
loginSubmit_url = 'http://server.xxx.net/index/index/loginSubmit'
# 患者列表
patientList_url = 'http://server.xxx.net/doctor/patient/index'
# 病例列表
caseList_url = 'http://server.xxx.net/doctor/visit/getCaseHistoryList'
# 化验报报告
laboratorySheetList_url = 'http://server.xxx.net/doctor/visit/getLaboratorySheetList'  # noqa: E501
# 影响图片
imagesList_url = 'http://server.xxx.net/doctor/visit/getImagesList'


# 获取token函数
def get_token():
    params = {'username': '188xxx85', 'password': 'winxxx0'}
    res = requests.post(loginSubmit_url, params).json()
    return res['token']


token = get_token()


# 获取患者列表函数
def get_patient_list():
    params = {'type': 'hz', 'search': '', 'token': token}
    res = requests.post(patientList_url, params).json()
    return res
# print(len(get_patient_list()))


# 根据patient_id与url获取患者不同类型信息函数
def get_detail(patient_id, url):
    params = {'patient_id': patient_id, 'token': token}
    res = requests.post(url, params).json()
    return res

# 获取病例列表
# print(get_detail('aa1982758a63af59ef713a767ae3f552',caseList_url))
# 获取化验报告
# print(get_detail('aa1982758a63af59ef713a767ae3f552',laboratorySheetList_url))
# 获取影像图片
# print(get_detail('3d1ad64611449a596c0e1709690754fc',imagesList_url))


# 下载图片函数
def get_imgs(img_url, save_path):
    response = requests.get(img_url)
    img = response.content
    file_name = img_url.split('/')[-1]
    with open(save_path+'/'+file_name, 'wb') as f:
        f.write(img)


def download_img(dict_list, file_dir):
    for i in dict_list:
        if patient_id == i['patient_id']:
            imgs_list = i['imgs']
            get_date = i['get_date']
            # print(patient_id,patient_phone,get_date,case_imgs)
            for k in imgs_list:
                # print(patient_id,patient_phone,get_date,k)
                file_path = file_dir + '/' + get_date
                if os.path.isdir(file_path):
                    # print('dir exists'mgs)
                    get_imgs(k, file_path)
                else:
                    # print('dir not exists')
                    os.makedirs(file_path)
                    get_imgs(k, file_path)
        else:
            print('空')


# 获取患者列表
patient_list = get_patient_list()

# 循环患者列表得到patient_phone和patient_id
for patient in patient_list:
    patient_id = patient['patient_id']
    patient_phone = patient['patient']['phone']
    # print(patient_id,'+',patient_phone)
    # 根据手机号创建目录
    case_dir = '/root/data/' + patient_phone + '/' + 'case/'
    laboratory_dir = '/root/data/' + patient_phone + '/' + 'laboratory/'
    images_dir = '/root/data/' + patient_phone + '/' + 'images/'

    # 根据手机号查询patient_id,得到病例照片链接,放入 data/手机号/case/日期/ 目录中
    case_list = get_detail(patient_id, caseList_url)
    download_img(case_list, case_dir)
    # 根据手机号查询patient_id,得到化验报告的照片链接,放入 data/手机号/laboratory/日期/ 目录中
    laboratory_list = get_detail(patient_id, laboratorySheetList_url)
    download_img(laboratory_list, laboratory_dir)
    # 根据手机号查询patient_id,得到影像的照片链接,放入 data/手机号/images/日期/ 目录中
    images_list = get_detail(patient_id, imagesList_url)
    download_img(images_list, images_dir)

python遍历目录修改文件名

# /usr/bin/env python
# -- coding:UTF-8 --

import os

root_dir = '/root/data/'
file_list = os.listdir(root_dir)
# print(file_list)

# 获取手机号目录
for a in file_list:
    shouji_dir = root_dir + a
    #print(shouji_dir)
    # 获取分类列表
    for b in shouji_dir:
        fenlei_list = os.listdir(shouji_dir)
        # 获取分类目录
    for c in fenlei_list:
        fenlei_dir = shouji_dir + '/' + c
        #print(fenlei_dir)
        # 获取日期列表
        for d in fenlei_dir:
            date_list = os.listdir(fenlei_dir)
            #print(date_list)
        # 获取日期目录
        for e in date_list:
            date_dir = fenlei_dir + '/' + e
            #print(date_dir)
            # 获取图片列表
            for f in date_dir:
                pic_list = os.listdir(date_dir)
                #print(pic_list)
            # 获取图片路径
            for g in pic_list:
                pic_dir = date_dir + '/' + g
                #print(pic_dir)
                # 获取图片数量与索引
                pic_nu = len(pic_list)
                pic_index = pic_list.index(g) + 1
                #print(pic_dir,pic_nu,pic_index)
                # 根据数量和索引修改文件名
                new_path = date_dir + '/' +  str(pic_nu) + '-' + str(pic_index) + '.jpg'
                os.rename(pic_dir,new_path)
                #print(new_path)

字节单位换算

#! /bin/bash
function checkNumber() {
    re='^[0-9]+(\.[0-9]+)?$'
    if ! [[ $1 =~ $re ]];then
        return 1
    fi
    return 0
}
function Convert() {
    if ! checkNumber $1;then
        echo "expect number but receive $1"
        return 1
    fi

    local gb=$((1024 * 1024 * 1024))
    local mb=$((1024 * 1024))
    local kb=1024

    if (($1 >= $gb));then
        echo "$(( $1 / $gb)) GB"
    elif (($1 >= $mb));then
        echo "$(( $1 / $mb)) MB"
    elif (($1 >= $kb));then
        echo "$(( $1 / $kb )) KB"
    else
        echo "$1 B"
    fi
}
Convert $*

对一组url测试能否访问成功

#!/bin/bash

url_list=(  #定义一个包含三个网址的数组 url_list
http://www.baidu.com
https://www.shiyanlou.com
http://www.google.com
)

wait(){   #定义倒计时函数 wait
    echo -n 'wait 3 second...'
    for ((i=0;i<3;i++))
    do
        echo -n ".";sleep 1  #每隔1秒打印一个点
    done
    echo
}

check_url(){
    wait   # 调用已经定义的 wait 函数

    #循环遍历 url_list 中的地址
    for ((i=0;i<`echo ${#url_list[*]}`;i++))
    do

        #检测是否可以访问数组元素中的地址
        wget -o /dev/null -T 3 --tries=1 --spider ${url_list[$i]} >/dev/null 2>&1  #--tries是设置尝试次数,--spider检查网址,后面的>/dev/null 2>&1是不保留任何输出

        if [ $? -eq 0 ];then   #如果返回值为0则表示访问成功
            echo "${url_list[$i]} success"
        else
            echo "${url_list[$i]} false"
        fi
    done
}

main(){  #定义主函数,即入口函数,应用程序运行时首先执行的代码
        check_url   #调用定义的 check_url 函数
}


main    #调用主函数

查询可用IP

#!/bin/bash
. /etc/init.d/functions
for var in {1..254};
do
    ip=172.16.50.$var
    ping -c2 $ip >/dev/null 2>&1
    if [ $? = 0 ];then
        action "$ip" /bin/true
    else
        action "$ip" /bin/false
    fi
done

MySQL单表数据同步脚本

#!/usr/bin/env bash
# Auth: liuli
# Version: v1.0, 2020/6/17
# Sys: CentOS 7.6
# Features: 用于同步研发数据库中的某些表至生产数据库

# set -xeuo pipefail

time=`date '+%Y-%m-%d-%H:%M'`
mkdir -p ./sql/${time}

db_Name="temp-tenant"
table_Name=(
interface_authority
interface_permissions
t_user_function_authority
t_user_function_permission
t_menu
)
# 研发环境
dev_IP="192.168.1.15"
dev_Port="3306"
dev_Pass="123456Aa."
# 生产环境
prod_IP="192.168.1.16"
prod_Port="23306"
prod_Pass="123456Aa."

# 导出研发环境的表
for i in ${table_Name[*]}
do
        mysqldump -h${dev_IP} -uroot -P${dev_Port} -p${dev_Pass} ${db_Name} ${i} > ./sql/${time}/dev.sql
done

# 导出生产环境的整个库
mysqldump -h${prod_IP} -uroot -P${prod_Port} -p${prod_Pass} ${db_Name} > ./sql/${time}/${db_Name}.sql

# 删除生产环境的表
for i in ${table_Name[*]}
do
        mysql -h${prod_IP} -uroot -P${prod_Port} -p${prod_Pass} -e "USE ${db_Name};DROP TABLE ${i}"
done

# 导入研发环境的表
mysql -h${prod_IP} -uroot -P${prod_Port} -p${prod_Pass} ${db_Name} < ./sql/${time}/dev.sql

Shell执行SQL示例

#!/usr/bin/env bash
# Auth: liuli
# Version: v1.0, 2020/6/24
# Sys: CentOS 7.6
# Features: 解除医生端小程序微信绑定的医生信息

#set -xeuo pipefail
clear

# 变量
USER=root
HOST=127.0.0.1
PORT=3306
PASSWORD=6yhn^YHN
DATABASE=temp-tenant

# 查询函数
function my_query ()
{
    query=$1
    mysql -u${USER} -h${HOST} -P${PORT} -p${PASSWORD} ${DATABASE} -e "${query}"
}

# 判断函数
function stat ()
{
    if [ $? -ne 0 ]; then
        echo $2
    else
        echo $1
    fi
}

# 程序开始
echo -n "你的unionid是:"
read UNIONID

# 判断UNIONID的正确性
if [ "${UNIONID}" = "" ];
then
    echo -e "\033[0;31m 未输入unionid \033[0m "
    exit 1
fi

if [ "${#UNIONID}" -ne "28" ];
then
    echo -e "\033[0;31m 请输入正确的unionid \033[0m "
    exit 1
fi

# 1、判断该unionid是否已绑定医生
sql1="SELECT count( id ) FROM t_user WHERE unionid = '${UNIONID}' AND type = '2';"
COUNT=$(my_query "${sql1}" | awk -F ")" '{print $NF}')

if [ "${COUNT}" -eq "1" ];then
    echo "已绑定医生"
else
    echo "该unionid未绑定医生"
    exit 0
fi

# 2、获取医生账号(account)和密码(password1、password2)
sql2="SELECT account,PASSWORD password1, ( SELECT PASSWORD FROM t_user_account WHERE account IN ( SELECT account FROM t_wechat_user_info WHERE unionid = '${UNIONID}' ) ) password2 FROM t_wechat_user_info WHERE unionid = '${UNIONID}';"

ACCOUNT=$(my_query "${sql2}"| sed -n "2p"| awk '{print $1}')
echo $(stat "获取医生账号成功" "获取医生账号失败")
echo "绑定的医生账号为:${ACCOUNT}"

PASSWD1=$(my_query "${sql2}"| sed -n "2p"| awk '{print $2}')
echo $(stat "获取password1成功" "获取password1失败")
echo "密码1:${PASSWD1}"

PASSWD2=$(my_query "${sql2}"| sed -n "2p"| awk '{print $3}')
echo $(stat "获取password2成功" "获取password2失败")
echo "密码2:${PASSWD2}"

# 3、修改用户信息
sql3="UPDATE t_user SET openid = '${ACCOUNT}', unionid = '${ACCOUNT}' WHERE unionid = '${UNIONID}' AND type = '2';"
my_query "${sql3}"
echo $(stat "修改用户信息成功" "修改用户信息失败")

# 4、增加微信信息
sql4="INSERT INTO t_wechat_user_info ( subscribe,openid,nickname,sex,language,city,province,country,headimgurl,subscribe_time,unionid,remark,groupid,tagids,subscribe_scene,qr_scene,qr_scene_str,create_time,account,password,update_time,source,is_bind) VALUES ( 0,'${ACCOUNT}','',1,NULL,'','','','',NULL,'${ACCOUNT}',NULL,NULL,NULL,NULL,NULL,NULL,'2020-06-05 17:13:17','${ACCOUNT}','${PASSWD1}','2020-06-24 09:44:37','2','0');"
my_query "${sql4}"
echo $(stat "增加微信信息成功" "增加微信信息失败")

# 5、删除角色信息
sql5="DELETE FROM t_user_role WHERE user_id IN ( SELECT id FROM t_user WHERE unionid = '${UNIONID}');"
my_query "${sql5}"
echo $(stat "删除角色信息成功" "删除角色信息失败")

# 6、删除用户信息
sql6="DELETE FROM t_user WHERE unionid = '${UNIONID}';"
my_query "${sql6}"
echo $(stat "删除用户信息成功" "删除用户信息失败")

# 7、删除用户账号
sql7="DELETE FROM t_user_account WHERE account IN ( SELECT account FROM t_wechat_user_info WHERE unionid = '${UNIONID}' );"
my_query "${sql7}"
echo $(stat "删除用户账号成功" "删除用户账号失败")

# 8、删除微信信息
sql8="DELETE FROM t_wechat_user_info WHERE unionid = '${UNIONID}';"
my_query "${sql8}"
echo $(stat "删除微信信息成功" "删除微信信息失败")

# 9、新建被删除的医生
sql9="INSERT INTO t_user_account ( account, password ) VALUES ( '${ACCOUNT}', '${PASSWD2}' );"
my_query "${sql9}"
echo $(stat "新建被删除的医生成功" "新建被删除的医生失败")

3.32.14. 参考文献: