crontab 到 运行 python 文件如果还没有 运行ning
crontab to run python file if not running already
我想通过 crontab 执行我的 python 文件,只有当它已经关闭或没有 运行ning 时。我尝试在 cron 选项卡中添加以下条目,但它不起作用
24 07 * * * pgrep -f test.py || nohup python /home/dp/script/test.py & > /var/tmp/test.out
test.py 如果我手动 运行 pgrep -f test.py || nohup python /home/dp/script/test.py & > /var/tmp/test.out
可以正常工作,如果我删除 pgrep -f test.py || 它也可以在 crontab 中工作从我的 crontab 中保留 24 07 * * * nohup python /home/dp/script/test.py & > /var/tmp/test.out
知道为什么我添加 pgrep -f 后 crontab 不起作用吗?有没有其他方法我可以 运行 test.py 一次来避免 运行 宁 test.py 的多个进程?
谢谢,
迪帕克
cron 可能会看到 pgrep -f test.py
进程以及 test.py
进程,从 pgrep
.
给你错误的结果
尝试不带 -f
的命令,这应该只查找出现的 test.py
或将 -f
替换为 -o
,这将查找最旧的出现。
您的另一个选择是在 test.py 中插入以下内容:
Pid = os.popen('pgrep -f test.py').read(5).strip()
这将允许您检查代码本身,如果它已经是 运行。
当来自 cron
的 运行 时,pgrep -f 将自己列为错误匹配
我用 script.py
运行 无限循环进行了测试。然后
pgrep -f script.py
...从终端,给 one pid,13132
,而 运行ning 从计划:
pgrep -f script.py > /path/to/out.txt
输出两个 pid,13132
和13635
.
因此我们可以得出结论,当 运行 来自 cron 时,命令 pgrep -f script.py
将自己列为匹配项。不确定如何以及为什么,但这很可能是由于 cron
运行 具有非常有限的环境变量集(HOME、LOGNAME 和 SHELL)这一事实间接引起的。
解决方案
来自(包装器)脚本的 运行 pgrep -f
使命令 not 列出自身,即使 运行 来自 cron
.随后,运行 来自 cron
的包装器:
#!/bin/bash
if ! pgrep -f 'test.py'
then
nohup python /home/dp/script/test.py & > /var/tmp/test.out
# run the test, remove the two lines below afterwards
else
echo "running" > ~/out_test.txt
fi
在应用程序内部检查应用程序是否 运行ning 通常是一个好主意,而不是从外部检查并启动它。在流程中管理流程,而不是期望另一个流程来做。
- 让 cron 运行 应用程序始终
- 在应用程序开始执行时,有一个锁定文件或类似的机制来判断进程是否已经 运行ning。
- 如果应用程序已经 运行ning,请更新上次测试时间的某处并中断新进程。
- 如果应用程序未 运行ning,请在某处登录并通知某人(如果需要)并触发进程启动。
这将确保您可以更好地控制进程的生命周期,并让您决定在出现故障时要做什么。
更不用说,如果要确保应用程序的正常运行时间很高,最好使用Monit等监控服务。同样,这将取决于您的应用程序是否添加了一个健全层,表明它是否正常。
自己在寻找解决方案时遇到了这个老问题。
使用psutil:
import psutil
import sys
from subprocess import Popen
for process in psutil.process_iter():
if process.cmdline() == ['python', 'your_script.py']:
sys.exit('Process found: exiting.')
print('Process not found: starting it.')
Popen(['python', 'your_script.py'])
您还可以使用上一个进程的开始时间来确定它是否 运行 太长并且可能被挂起:
process.create_time()
该过程还有大量其他有用的元数据。
问题是 pgreg -f
正在识别 cron 用于 运行 命令本身的 shell 脚本。
我通过在 rot13 中编码文件名并用 python one-liner 解码它解决了 pgrep -f
问题,因为我不想添加脚本包装器只是为了计划任务。即:
pgrep -f $(python3 -c 'import codecs; print(codecs.decode("grfg.cl", "rot13"))') || nohup python /home/dp/script/test.py & > /var/tmp/test.out
已添加:您可以使用 tr 解码 rot13,这将导致更短且更易于阅读的命令:
pgrep -f $(echo grfg.cl | tr a-zA-Z n-za-mN-ZA-M) || nohup python /home/dp/script/test.py & > /var/tmp/test.out
为什么只检查 pid 已经是这样 运行
Pid = os.popen('pgrep -f myscript.py').readlines()
if len(Pid) > 1:
exit()
您可以创建名为 test.py 的测试文件
如果您再次尝试执行同一个文件,它应该会退出。
import time
import os
from tempfile import TemporaryFile
import subprocess
def cron_running(p_name):
run_cnt=0
with TemporaryFile() as tf:
subprocess.call(["ps","ax"], stdout=tf)
tf.seek(0)
for line in tf:
if p_name in line.decode('ascii'):
run_cnt+=1
if run_cnt > 1:
quit()
if cron_running(os.path.basename(__file__)):
print("cron is already running")
quit()
for i in range(60):
time.sleep(1)
我想通过 crontab 执行我的 python 文件,只有当它已经关闭或没有 运行ning 时。我尝试在 cron 选项卡中添加以下条目,但它不起作用
24 07 * * * pgrep -f test.py || nohup python /home/dp/script/test.py & > /var/tmp/test.out
test.py 如果我手动 运行 pgrep -f test.py || nohup python /home/dp/script/test.py & > /var/tmp/test.out
可以正常工作,如果我删除 pgrep -f test.py || 它也可以在 crontab 中工作从我的 crontab 中保留 24 07 * * * nohup python /home/dp/script/test.py & > /var/tmp/test.out
知道为什么我添加 pgrep -f 后 crontab 不起作用吗?有没有其他方法我可以 运行 test.py 一次来避免 运行 宁 test.py 的多个进程? 谢谢, 迪帕克
cron 可能会看到 pgrep -f test.py
进程以及 test.py
进程,从 pgrep
.
给你错误的结果
尝试不带 -f
的命令,这应该只查找出现的 test.py
或将 -f
替换为 -o
,这将查找最旧的出现。
您的另一个选择是在 test.py 中插入以下内容:
Pid = os.popen('pgrep -f test.py').read(5).strip()
这将允许您检查代码本身,如果它已经是 运行。
当来自 cron
的 运行 时,pgrep -f 将自己列为错误匹配我用 script.py
运行 无限循环进行了测试。然后
pgrep -f script.py
...从终端,给 one pid,13132
,而 运行ning 从计划:
pgrep -f script.py > /path/to/out.txt
输出两个 pid,13132
和13635
.
因此我们可以得出结论,当 运行 来自 cron 时,命令 pgrep -f script.py
将自己列为匹配项。不确定如何以及为什么,但这很可能是由于 cron
运行 具有非常有限的环境变量集(HOME、LOGNAME 和 SHELL)这一事实间接引起的。
解决方案
来自(包装器)脚本的运行 pgrep -f
使命令 not 列出自身,即使 运行 来自 cron
.随后,运行 来自 cron
的包装器:
#!/bin/bash
if ! pgrep -f 'test.py'
then
nohup python /home/dp/script/test.py & > /var/tmp/test.out
# run the test, remove the two lines below afterwards
else
echo "running" > ~/out_test.txt
fi
在应用程序内部检查应用程序是否 运行ning 通常是一个好主意,而不是从外部检查并启动它。在流程中管理流程,而不是期望另一个流程来做。
- 让 cron 运行 应用程序始终
- 在应用程序开始执行时,有一个锁定文件或类似的机制来判断进程是否已经 运行ning。
- 如果应用程序已经 运行ning,请更新上次测试时间的某处并中断新进程。
- 如果应用程序未 运行ning,请在某处登录并通知某人(如果需要)并触发进程启动。
这将确保您可以更好地控制进程的生命周期,并让您决定在出现故障时要做什么。
更不用说,如果要确保应用程序的正常运行时间很高,最好使用Monit等监控服务。同样,这将取决于您的应用程序是否添加了一个健全层,表明它是否正常。
自己在寻找解决方案时遇到了这个老问题。
使用psutil:
import psutil
import sys
from subprocess import Popen
for process in psutil.process_iter():
if process.cmdline() == ['python', 'your_script.py']:
sys.exit('Process found: exiting.')
print('Process not found: starting it.')
Popen(['python', 'your_script.py'])
您还可以使用上一个进程的开始时间来确定它是否 运行 太长并且可能被挂起:
process.create_time()
该过程还有大量其他有用的元数据。
问题是 pgreg -f
正在识别 cron 用于 运行 命令本身的 shell 脚本。
我通过在 rot13 中编码文件名并用 python one-liner 解码它解决了 pgrep -f
问题,因为我不想添加脚本包装器只是为了计划任务。即:
pgrep -f $(python3 -c 'import codecs; print(codecs.decode("grfg.cl", "rot13"))') || nohup python /home/dp/script/test.py & > /var/tmp/test.out
已添加:您可以使用 tr 解码 rot13,这将导致更短且更易于阅读的命令:
pgrep -f $(echo grfg.cl | tr a-zA-Z n-za-mN-ZA-M) || nohup python /home/dp/script/test.py & > /var/tmp/test.out
为什么只检查 pid 已经是这样 运行
Pid = os.popen('pgrep -f myscript.py').readlines()
if len(Pid) > 1:
exit()
您可以创建名为 test.py 的测试文件 如果您再次尝试执行同一个文件,它应该会退出。
import time
import os
from tempfile import TemporaryFile
import subprocess
def cron_running(p_name):
run_cnt=0
with TemporaryFile() as tf:
subprocess.call(["ps","ax"], stdout=tf)
tf.seek(0)
for line in tf:
if p_name in line.decode('ascii'):
run_cnt+=1
if run_cnt > 1:
quit()
if cron_running(os.path.basename(__file__)):
print("cron is already running")
quit()
for i in range(60):
time.sleep(1)