shell并发执行脚本程序

#!/usr/bin/env bash
:<<!
多进程执行脚本
!

source ~/.bashrc
#set +x  # 执行指令后,会先显示该指令及所下的参数
#set +e  # 若指令传回值不等于0,则立即退出shell

if [[ $# -ne 2 ]]; then
    # 如果传入参数数量不等于2,则退出程序
    echo -e "\033[1;32mUsage:\n\t从2017-01-01开始到2018-01-01(不包括2018-01-01这天)结束\n\texample:\t$0 20170101 20180101\033[0m"
    exit
fi

STA_DATE=$1  # 开始日期
END_DATE=$2  # 结束日期
cur_date=${STA_DATE}  # 当前日期,这是一个变量
echo -e "\033[1;32mStart date: ${STA_DATE}\033[0m"
echo -e "\033[1;32mEnd date: ${END_DATE}\033[0m"

THREAD=5  # 声明并发进程数,即设置管道的最大任务数
TMPFIFO=/tmp/$$.fifo  # 声明管道名称,`$$`表示脚本运行的进程PID
mkfifo ${TMPFIFO}  # 创建管道
exec 8<>${TMPFIFO}  # 创建文件标示`8`,这个数字可以为除0, 1, 2之外的所有未声明过的字符,以读写模式操作管道
rm -rf ${TMPFIFO}  # 清除创建的管道文件

#为并发线程创建同样个数的占位
for((i=1; i<=${THREAD}; i++))
do
    # 借用read命令一次读取一行的特性,使用一个echo默认输出一个换行符到文件描述符中,
    # 来确保每一行只有一个线程占位;这里让人联想到生产者和消费者模型,
    # 管道文件充当消息队列,来记录消费者的需求,然后由生产者去领任务,
    # 并完成任务,这里运用了异步解耦的思想.
    echo >&8  # 写一个空行到管道里,因为管道文件的读取以行为单位
done

while [[ ${cur_date} -lt ${END_DATE} ]]
do
    # 从文件描述符管道中,获取一个管道的线程占位然后开始执行操作;
    # read中 -u 后面跟fd,表示从文件描述符中读入,该文件描述符可以是exec新开启的。
    read -u8  # 读取管道中的一行,每次读取后,管道都会少一行
    {
        echo ${cur_date}
        sh ./run.sh ${cur_date}  # 运行脚本
        echo >&8  # #每次执行完子脚本后,再增加一个空行,这样下面的进程才可以继续执行
    }& #这里要放入后台去,否则并发实现不了

    cur_date=$(date +%Y%m%d -d "${cur_date} +1 day")  # cur_date +1 days
done

wait                #等待父进程的子进程都执行结束后再结束父进程
exec 8>&-           #关闭fd8的管道

echo -e "\033[1;36mDone!\033[0m"
exit 0

你可能感兴趣的:(编程语言-Python)