如何完善Wrapper脚本实现批量Shell脚本并行执行?
完善Wrapper脚本实现批量并行执行Shell脚本
嘿,我来帮你把这个Wrapper脚本补全,解决手动执行100次nohup的麻烦事儿。核心思路是读取日期文件里的每个日期,并行启动所有目标脚本,同时做好日志隔离和基础校验,话不多说直接上干货:
第一步:先把要执行的脚本列表搞定
你有100个脚本,总不能一个个写在代码里硬编码吧?推荐两种方式管理脚本列表:
- 方式1:用数组直接定义(适合脚本数量固定、路径不常变的情况)
# 把你的100个脚本路径都填在这里,每行一个 TARGET_SCRIPTS=( "/opt/scripts/abc.sh" "/opt/scripts/abc1.sh" "/opt/scripts/abc2.sh" # ... 剩下的97个脚本依次添加 )
- 方式2:用外部清单文件(适合脚本经常新增/修改的情况)
先创建一个script_list.txt,每行写一个脚本的绝对路径,然后在脚本里读取:
# 从清单文件加载所有脚本路径 TARGET_SCRIPTS=($(cat /opt/scripts/script_list.txt))
第二步:完善你的Wrapper主逻辑
把你写的开头和并行执行、日志处理的逻辑结合起来,最终脚本如下:
#!/bin/bash # 记录脚本启动时间 echo "*** Wrapper Start Time ---> `date '+%Y-%m-%d %H:%M:%S'` ***" # -------------------------- 配置区 -------------------------- # 要执行的脚本列表(二选一:数组或读取外部文件) TARGET_SCRIPTS=( "/opt/scripts/abc.sh" "/opt/scripts/abc1.sh" # ... 你的其他脚本 ) # TARGET_SCRIPTS=($(cat /opt/scripts/script_list.txt)) # 日志存放目录(提前用mkdir -p创建好,比如/var/log/script_runs) LOG_DIR="/var/log/script_runs" # ----------------------------------------------------------- # 确保日志目录存在 mkdir -p "${LOG_DIR}" # 遍历日期文件中的每个日期 for raw_date in $(cat datefile_Prepaid_data); do # 处理日期格式(如果datefile里的日期有多余字符,这里调整,比如只取第一列) exec_date=$(echo "${raw_date}" | awk '{print $1}') # 校验日期格式是否合法,避免无效日期导致脚本出错 if ! date -d "${exec_date}" >/dev/null 2>&1; then echo "⚠️ Invalid date format: ${exec_date}, skipping this date..." continue fi echo "=== Starting all scripts for date: ${exec_date} at `date '+%Y-%m-%d %H:%M:%S'` ===" # 并行启动所有脚本 for script_path in "${TARGET_SCRIPTS[@]}"; do # 检查脚本是否存在且可执行 if [[ ! -x "${script_path}" ]]; then echo "⚠️ Script ${script_path} is missing or not executable, skipping..." continue fi # 生成独立的日志文件名(脚本名_日期.log),避免日志混乱 script_name=$(basename "${script_path}") log_file="${LOG_DIR}/${script_name}_${exec_date}.log" # 用nohup后台执行,把标准输出和错误都重定向到日志 nohup "${script_path}" "${exec_date}" > "${log_file}" 2>&1 & # 可选:记录每个脚本的PID,方便后续排查 echo "$! | ${script_name} | ${exec_date}" >> "${LOG_DIR}/running_pids_${exec_date}.txt" echo "✅ Launched ${script_name} for ${exec_date} - Log: ${log_file}" done # 可选:如果需要等当前日期的所有脚本执行完再处理下一个日期,取消下面这行注释 # wait echo "=== All scripts launched for date: ${exec_date} ===" done echo "*** Wrapper End Time ---> `date '+%Y-%m-%d %H:%M:%S'` ***"
几个关键细节说明
- 日志隔离:每个脚本+日期对应独立日志,再也不用在大日志里翻找某一天某个脚本的输出了。
- 资源控制:默认是100个脚本同时后台跑,如果担心服务器CPU/内存扛不住,可以用
xargs限制并行数,比如把上面的脚本循环替换成:
# 每次最多并行启动10个脚本,根据服务器资源调整数字 printf "%s\n" "${TARGET_SCRIPTS[@]}" | xargs -I {} -P 10 nohup {} "${exec_date}" > "${LOG_DIR}/$(basename {})_${exec_date}.log" 2>&1 &
- 合法性校验:加了日期格式检查和脚本存在性检查,避免无效输入导致的一堆报错。
- PID记录:可选的PID记录功能,方便你后续查看哪些脚本还在运行,或者强制终止异常进程。
额外优化小建议
- 可以加个错误告警:比如定期检查日志里的
ERROR关键词,发现异常就发邮件通知你。 - 如果是每日固定时间运行,可以把这个Wrapper脚本加到
crontab里,彻底自动化。
内容的提问来源于stack exchange,提问作者Sas
相关产品推荐
相关产品推荐

