【问题标题】:Run python script from shell script using crontab使用 crontab 从 shell 脚本运行 python 脚本
【发布时间】:2022-01-18 13:33:35
【问题描述】:

我有一个 shell 脚本 main.sh,它运行一个 python 脚本 main.py。当我手动运行main.sh 脚本时,执行正常(注意我正在使用root 用户手动运行它)并且python 脚本按预期工作。但是,当我从 crontab 尝试相同的操作时,它每 30 分钟运行一次 main.sh 脚本,然后 python 脚本没有被执行。(我已经完成了 chmod u+x main.sh em> 使其可执行)

下面给出的 crontab 也是 root 用户的

我的 crontab 文件: */30 * * * * /home/opc/python_scripts/main.sh >> /home/opc/cron.log.

我的 main.sh 文件:

#!/bin/bash
output=$(sh /home/opc/python_scripts/url.sh)
echo "$output"
searchstring="url is up, login service is up and oc console is up"
if [[ "$output" == *"$searchstring"* ]] ; then
    echo "URL is up"
    sudo python3 /home/opc/python_scripts/main.py >> /home/opc/pyfile.log
else
    echo "URL is Down"
    sudo python3 /home/opc/python_scripts/disable_crr.py
fi

我知道它正在输入第一个 if 条件并且它还在打印“URL is up”语句,我有另一个日志文件记录了这一点。当我手动运行它时,我可以看到即使是 python 脚本也可以正常运行,但是使用 crontab 它会卡在echo "URL is up",之后就没有执行了

我为解决这个问题所做的事情:

  1. 我已经看到类似问题的解决方案,例如-Calling a python script from shell script cronShell Script: Execute a python program from within a shell script,但在所有这些问题中,用户都无法从 shell 脚本手动运行 python 脚本。我可以手动运行它,但如果我使用 cronjob,我就会遇到问题。

  2. 当我在这些脚本所在的目录中运行 ls -la 时,这些文件的所有权如下:

main.sh root root  
main.py opc opc

此外,我在我的 python 脚本顶部添加了#!/usr/bin/env python3,因为我认为这是一个类似问题的解决方案,但没有奏效,只能手动工作,而不是使用 crontab。

如何使用 crontab 运行它?

【问题讨论】:

  • 您是否尝试过像这样运行main.sh/home/opc/python_scripts/main.sh >> /home/opc/cron.logwithout crontab?
  • @alexzander 是的,我做到了,我可以手动运行文件,但只有 crontab 给我带来了问题。

标签: python linux bash shell


【解决方案1】:

您是否尝试删除sudo

但是,由于您必须每 30 分钟运行一次,您也可以考虑:

  • 使用schedule直接在python中调度
  • 使用 python 库编写您的 CronTab 文件
  • 使用 docker 在更孤立的环境中运行,并使用 crontab 调度 docker run
  • 最后,如果您可以访问它,您还可以考虑在 k8s 集群等上使用 cronjob

【讨论】:

  • 我确实删除了 sudo,但没有任何改变,我查看了“schedule”,但是我想使用 cron,因为我从未使用过 schedule,这是一个团队项目,所以 cronjob 中还有其他脚本取决于此脚本的执行。关于k8s和docker,之前没用过。
【解决方案2】:

您正在尝试使用 sudo 执行脚本,但 cron 无法提示您输入密码。由于这是 root 的 crontab,因此您不需要使用 sudo。

如果必须在 cron 中使用 sudo,则需要通过 /etc/sudoers 将这些命令指定为无密码。沿着这些思路应该可以工作。

opc ALL=(root) NOPASSWD: /home/opc/python_scripts/main.py

【讨论】:

  • 是的,我尝试了您的建议,但没有影响,因为它仍然无法执行。行为仍然相同。即使我使用 sudo 它也不会要求我输入密码,问题是这是 Oracle 云上的一个实例,所以当我写 sudo 时它不会要求输入密码,如果我写 sudo su,它会直接将我带到 root 用户,从不要求输入密码。我的linux是centos7
【解决方案3】:

所以我不知道问题是什么,但我解决了。

如何:

正如我之前在我的问题中提到的那样,我已经分别尝试了上述两个问题。

  1. 现在我所做的是,实现了Calling a python script from shell script cron 的给定答案,其中我只使用了这部分答案:
#!/usr/bin/env bash
dirName=`dirname $0`
baseName=`basename $0`
arg1=$1
arg2=$2
cd ${dirName} && python ./room_wise.py arg1 arg2
  1. 从第二个问题Shell Script: Execute a python program from within a shell script,我使用João Víctor回答方法2并将python替换为python3。

我不完全明白问题出在哪里,但是当我同时使用这两种解决方案时,它开始起作用了。同样正如其他人在这篇文章中提到的那样,如果您使用的是 root 的 crontab,请不要使用 sudo,否则可能会导致授权问题。这样就解决了,如果有人有更好的理解,那么也请添加您的答案。

【讨论】: