You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:通过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的环境特性差异:

  1. 子脚本路径找不到:Cron默认工作目录是用户主目录(/root),而run_scripts.py直接用相对路径调用子脚本,Cron运行时会在/root下查找这些文件,自然无法找到。
  2. Python解释器路径不明确:subprocess.call(["python", program])里的python未指定虚拟环境的绝对路径,Cron的环境变量PATH与手动执行不同,可能调用系统默认Python而非虚拟环境版本,导致依赖缺失。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:05:22