Python 某些脚本在使用subprocess.Popen()时失败,但在crontab或手动运行中运行正常

Python 某些脚本在使用subprocess.Popen()时失败,但在crontab或手动运行中运行正常,python,cron,subprocess,debian,Python,Cron,Subprocess,Debian,我有一个cron.py脚本,它在Debian 10服务器上的crontab下运行。该文件有效地取代了crontab,因此可以通过Git更新脚本运行crontab运行cron.py,cron.py使用运行Python脚本 大多数脚本使用此系统运行良好。然而,有两个项目未能完成运行。开始时,跑一小段时间(通常不到一分钟),然后无限期地挂起。两个脚本: reports.py连接到Amazon MWS并将以前请求的报告下载到本地目录 inventory.py解析数千个本地文件,并将其内容上传到谷歌表单

我有一个
cron.py
脚本,它在Debian 10服务器上的crontab下运行。该文件有效地取代了crontab,因此可以通过Git更新脚本运行
crontab
运行
cron.py
cron.py
使用运行Python脚本

大多数脚本使用此系统运行良好。然而,有两个项目未能完成运行。开始时,跑一小段时间(通常不到一分钟),然后无限期地挂起。两个脚本:

  • reports.py
    连接到Amazon MWS并将以前请求的报告下载到本地目录
  • inventory.py
    解析数千个本地文件,并将其内容上传到谷歌表单
这两个进程是完全独立的,除了用于日志记录的AWS Cloud Watch日志外,它们访问的资源不同。他们两人相隔1小时跑步

我试过的大部分只是调查。我没有得到任何异常,没有出现被击中,脚本只是硬停止,并在2小时超时后清理。如果我
strace
锁定进程,它只显示最后一次日志调用

在对此进行故障排除时,我构建了CloudWatch指标来跟踪每个脚本的峰值内存使用情况。许多其他脚本使用的峰值内存比其他脚本多得多,所以我认为这与内存无关。我从切换到以启用此功能

如果我通过SSH手动运行脚本,或者在本地Windows机器上运行脚本,那么它们工作得非常好。作为一个临时解决方案,在正常运行时间后的半小时内通过crontab运行这些进程,这样我仍然可以在进程正常运行时获取故障日志

Popen呼叫如下(大量复制粘贴和匿名):

TIMEOUT=60*60*2
进程=[]
args=['python','cron.d/scriptname.py']
使用shell=False
如果os.name='nt':
使用shell=True
po=psutil.Popen(
args,
stdout=子流程.PIPE,
stderr=子流程.PIPE,
外壳=使用外壳,
cwd=os.path.join(abspath、to、script),
text=True,
universal_newlines=True,
)
进程。追加(po)
而len(过程)>0:
对于过程中的过程:
如果((datetime.now()-开始时间)。总秒数()>超时):
程序kill()
时间。睡眠(10)#等待进程处理终止信号
其他:
如果proc.poll()为无:
时间。睡眠(1)
持续
(stdoutdata,stderdata)=过程通信()
returncode=proc.returncode
#根据此处的返回代码记录流程成功/失败
进程。删除(proc)
我相信在这方面会有一些问题,因为在
cron.py
中有很多事情正在进行,我很高兴提供更多信息


编辑:添加了
使用shell
设置来编码。这是为了可以执行Windows测试(如果
shell=False
,Windows中不会传递环境和其他资源)。

顺便说一句,一个真正的程序员应该给出一个比
cron.py
更好的名称。通常问题是:不同的环境(cron设置路径和合理值的归属)。不使用绝对路径(因此这取决于何时进行PWD调用)。添加您得到的异常(行和异常错误应该足够了)。注意:还不清楚您在哪里安装了crontab。作为用户还是作为系统(由root用户运行)?很抱歉,我不符合您对“真正的程序员”的标准。环境是一样的。所有的路径都是绝对的。不会引发异常,子进程将被硬冻结,并被超时捕获和终止。如果抛出异常并且脚本失败,它将被捕获在
sdterrdata
和脚本自己的try-except块中。Crontab是以用户身份安装的。脚本名和大部分代码都是用通用脚本和变量名给出的,上面的代码不会像编写的那样执行。这是出于保密的目的。此外,如果用户在终端(python scriptname.py或python/absolute path/scriptname.py)中手动调用脚本,但通过
subprocess.Popen()
psutil.Popen()
作为子进程启动时会在随机时间间隔后出现硬锁失败,则脚本运行良好。脚本在冻结前的1到8分钟内运行,没有给出任何原因。对不起,这是个玩笑。不幸的是,我看到许多程序员(和更糟糕的老师)使用了糟糕的变量名。你知道…当其他人应该修复代码时。所以这只是一个坏习惯(你描述的是“它是什么”,而不是正确的“它做什么”)。顺便说一句,一个真正的程序员应该给一个比cron.py更好的名字。通常问题是:不同的环境(cron设置路径和合理值的归属)。不使用绝对路径(因此这取决于何时进行PWD调用)。添加您得到的异常(行和异常错误应该足够了)。注意:还不清楚您在哪里安装了crontab。作为用户还是作为系统(由root用户运行)?很抱歉,我不符合您对“真正的程序员”的标准。环境是一样的。所有的路径都是绝对的。不会引发异常,子进程将被硬冻结,并被超时捕获和终止。如果抛出异常并且脚本失败,它将被捕获在
sdterrdata
和脚本自己的try-except块中。Crontab是以用户身份安装的。脚本名和大部分代码都是用通用脚本和变量名给出的,上面的代码不会像编写的那样执行。这是出于保密的目的。此外,如果用户在终端(python scriptname.py或python/absolute path/scriptname.py)中手动调用脚本,但通过
subprocess.Popen()
psutil.Popen()
作为子进程启动时会在随机时间间隔后出现硬锁失败,则脚本运行良好。脚本可以在任何地方运行