求助:通过Crontab调用Bash脚本执行Python脚本未正常运行
问题:Crontab调用Shell脚本运行Python脚本失败(手动执行正常)
相关文件内容
run_scripts.py
import subprocess program_list = ["phone_search.py", "benefit_id_search.py"] for program in program_list: subprocess.call(["python", program]) print("Finished:" + program)
cron.sh
#!/bin/bash set -x echo "$PWD" pid_file='/root/pipedrive_CRM/run_scripts.pid' if [ ! -s "$pid_file" ] || ! kill -0 $(cat $pid_file) > /dev/null 2>&1; then echo $$ > "$pid_file" exec /root/pipedrive_CRM/venv/bin/python /root/pipedrive_CRM/run_scripts.py fi
Crontab配置
52 21 * * * /root/pipedrive_CRM/cron.sh
手动运行追踪输出
+ echo /root/pipedrive_CRM /root/pipedrive_CRM + pid_file=/root/pipedrive_CRM/run_scripts.pid + '[' '!' -s /root/pipedrive_CRM/run_scripts.pid ']' ++ cat /root/pipedrive_CRM/run_scripts.pid + kill -0 733932 + echo 734004 + exec /root/pipedrive_CRM/venv/bin/python /root/pipedrive_CRM/run_scripts.py
问题根源分析
手动执行正常但Cron失效,核心问题出在Python脚本的路径调用逻辑和Cron的环境特性差异:
- 子脚本路径找不到:Cron默认工作目录是用户主目录(/root),而
run_scripts.py直接用相对路径调用子脚本,Cron运行时会在/root下查找这些文件,自然无法找到。 - Python解释器路径不明确:
subprocess.call(["python", program])里的python未指定虚拟环境的绝对路径,Cron的环境变量PATH与手动执行不同,可能调用系统默认Python而非虚拟环境版本,导致依赖缺失。 - PID文件的潜在干扰:如果手动运行后PID文件未被清理(比如进程正常结束但pid文件残留),Cron运行时会检测到pid文件存在,若之前的PID被系统复用,可能误判进程仍在运行,直接跳过执行。
修复方案
1. 修改Python脚本,使用绝对路径调用子脚本和解释器
import subprocess import os # 获取当前脚本所在目录 script_dir = os.path.dirname(os.path.abspath(__file__)) # 虚拟环境Python的绝对路径 python_path = "/root/pipedrive_CRM/venv/bin/python" program_list = ["phone_search.py", "benefit_id_search.py"] for program in program_list: # 拼接子脚本的绝对路径 program_path = os.path.join(script_dir, program) subprocess.call([python_path, program_path]) print("Finished:" + program)
2. 优化Shell脚本,确保工作目录正确并处理PID文件
#!/bin/bash set -x # 切换到脚本所在目录,避免路径问题 cd /root/pipedrive_CRM echo "$PWD" pid_file='./run_scripts.pid' # 安全检查旧进程状态 if [ -s "$pid_file" ]; then old_pid=$(cat "$pid_file") if kill -0 "$old_pid" > /dev/null 2>&1; then echo "Process $old_pid is running, exiting." exit 0 fi fi # 写入新PID并设置脚本退出时自动清理PID文件 echo $$ > "$pid_file" trap "rm -f $pid_file" EXIT /root/pipedrive_CRM/venv/bin/python /root/pipedrive_CRM/run_scripts.py
3. Crontab配置添加日志输出,方便后续排查
52 21 * * * /root/pipedrive_CRM/cron.sh >> /root/pipedrive_CRM/cron.log 2>&1
内容的提问来源于stack exchange,提问作者X-something
相关产品推荐
相关产品推荐

