通过 crontab 执行 Python 脚本
Posted
技术标签:
【中文标题】通过 crontab 执行 Python 脚本【英文标题】:Execute Python script via crontab 【发布时间】:2012-02-02 10:01:16 【问题描述】:我正在尝试使用 Linux crontab 执行 Python 脚本。我想每 10 分钟运行一次这个脚本。
我找到了很多解决方案,但都没有奏效。例如:在 /etc/cron.d 编辑 anacron 或使用 crontab -e
。我把这一行放在文件的末尾,但它并没有改变任何东西。我必须重新启动任何服务吗?
*/2 * * * * /usr/bin/python /home/souza/Documets/Listener/listener.py
我必须编辑什么文件来配置它?
这是脚本。
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import json
import os
import pycurl
import sys
import cStringIO
if __name__ == "__main__":
name_server_standart = "Server created by script %d"
json_file_standart = " \"server\" : \"name\" : \"%s\", \"imageRef\" : \"%s\", \"flavorRef\" : \"%s\" "
curl_auth_token = pycurl.Curl()
gettoken = cStringIO.StringIO()
curl_auth_token.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1")
curl_auth_token.setopt(pycurl.POST, 1)
curl_auth_token.setopt(pycurl.HTTPHEADER, ["X-Auth-User: cpca",
"X-Auth-Key: 438ac2d9-689f-4c50-9d00-c2883cfd38d0"])
curl_auth_token.setopt(pycurl.HEADERFUNCTION, gettoken.write)
curl_auth_token.perform()
chg = gettoken.getvalue()
auth_token = chg[chg.find("X-Auth-Token: ")+len("X-Auth-Token: ") : chg.find("X-Server-Management-Url:")-1]
token = "X-Auth-Token: 0".format(auth_token)
curl_auth_token.close()
#----------------------------
getter = cStringIO.StringIO()
curl_hab_image = pycurl.Curl()
curl_hab_image.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7")
curl_hab_image.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
curl_hab_image.setopt(pycurl.HTTPHEADER, [token])
curl_hab_image.setopt(pycurl.WRITEFUNCTION, getter.write)
#curl_list.setopt(pycurl.VERBOSE, 1)
curl_hab_image.perform()
curl_hab_image.close()
getter = cStringIO.StringIO()
curl_list = pycurl.Curl()
curl_list.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers/detail")
curl_list.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
curl_list.setopt(pycurl.HTTPHEADER, [token])
curl_list.setopt(pycurl.WRITEFUNCTION, getter.write)
#curl_list.setopt(pycurl.VERBOSE, 1)
curl_list.perform()
curl_list.close()
#----------------------------
resp = getter.getvalue()
con = int(resp.count("status"))
s = json.loads(resp)
lst = []
for i in range(con):
lst.append(s['servers'][i]['status'])
for j in range(len(lst)):
actual = lst.pop()
print actual
if actual != "ACTIVE" and actual != "BUILD" and actual != "REBOOT" and actual != "RESIZE":
print "Entra no If"
f = file('counter', 'r+w')
num = 0
for line in f:
num = line
content = int(num)+1
ins = str(content)
f.seek(0)
f.write(ins)
f.truncate()
f.close()
print "Contador"
json_file = file('json_file_create_server.json','r+w')
name_server_final = name_server_standart % content
path_to_image = "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7"
path_to_flavor = "http://192.168.100.241:8774/v1.1/nuvemcpca/flavors/1"
new_json_file_content = json_file_standart % (name_server_final, path_to_image, path_to_flavor)
json_file.seek(0)
json_file.write(new_json_file_content)
json_file.truncate()
json_file.close()
print "Json File"
fil = file("json_file_create_server.json")
siz = os.path.getsize("json_file_create_server.json")
cont_size = "Content-Length: %d" % siz
cont_type = "Content-Type: application/json"
accept = "Accept: application/json"
c_create_servers = pycurl.Curl()
logger = cStringIO.StringIO()
c_create_servers.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers")
c_create_servers.setopt(pycurl.HTTPHEADER, [token, cont_type, accept, cont_size])
c_create_servers.setopt(pycurl.POST, 1)
c_create_servers.setopt(pycurl.INFILE, fil)
c_create_servers.setopt(pycurl.INFILESIZE, siz)
c_create_servers.setopt(pycurl.WRITEFUNCTION, logger.write)
print "Teste perform"
c_create_servers.perform()
print logger.getvalue()
c_create_servers.close()
【问题讨论】:
当你说“它不会改变任何东西”时。它是否显示错误,它不运行?行为是什么? 是故意使用“Documets”而不是“Documents”吗? 根本不会发生任何事情。 :( 这种类型超出了问题的范围,但是,您希望您的“listener.py”脚本做什么?它会做任何表明它已经运行的事情吗? ps -ef |在命令行中 grep 'crond' 以检查 cron 是否正在运行。 不,这个脚本将几个 cURL 的命令发送到另一台计算机。当我执行“ps -f | grep 'crond'”时,它返回:“souza 4736 3947 0 14:01 pts/1 00:00:00 grep --color=auto crond” 【参考方案1】:只需使用crontab -e
并按照教程here. 进行操作
请参阅第 3 点以获取有关如何指定频率的指南。
根据您的要求,实际上应该是:
*/10 * * * * /usr/bin/python script.py
【讨论】:
我按照本教程进行操作,但是当我保存文件时会出现一条消息:“/tmp/crontab.JTQ0My/crontab”:22: crontab 文件中出现严重错误,无法安装。是否要重试相同的编辑? (y/n)”如果我输入“y”,我已经返回到文件编辑。如果我输入“n”,则文件不会被保存。我在文件的最后一行添加这一行:“/1 * * * * /usr/bin/python script.py" @guisantogui 教程中有一点解释说,并非所有操作系统都支持使用“/1”。你在什么操作系统上运行这个? @guisantogui 刚刚注意到您在“/”之前缺少一个“*” 另一种方法是在您的 script.py 中添加一个 env 声明。请参阅我的 cmets 以了解接受的解决方案:***.com/questions/25633737/python-crontab-and-paths 如果你只想在给定目录中执行script.py
怎么办?【参考方案2】:
把你的脚本放在一个文件foo.py
开头
#!/usr/bin/python
然后使用该脚本授予执行权限
chmod a+x foo.py
并在crontab
中使用foo.py
文件的完整路径。
请参阅处理shebang 的execve(2) 的文档。
【讨论】:
@Tomer 如果它们是 POSIXsh
shell 脚本,那么是的。如果它们使用特定于 ksh
、zsh
或 bash
的非标准功能,那么它们需要使用该特定 shell 运行。【参考方案3】:
正如您所提到的,它不会改变任何东西。
首先,您应该从 crontab 执行中重定向 standard input 和 standard error,如下所示:
*/2 * * * * /usr/bin/python /home/souza/Documets/Listener/listener.py > /tmp/listener.log 2>&1
然后您可以查看文件/tmp/listener.log
,看看脚本是否按预期执行。
其次,我猜你所说的改变任何东西的意思是通过观察你的程序创建的文件:
f = file('counter', 'r+w')
json_file = file('json_file_create_server.json', 'r+w')
上面的 crontab 作业不会在目录/home/souza/Documets/Listener
中创建这些文件,因为 cron 作业不在此目录中执行,并且您在程序中使用相对路径。所以要在目录/home/souza/Documets/Listener
中创建这个文件,下面的 cron 作业就可以了:
*/2 * * * * cd /home/souza/Documets/Listener && /usr/bin/python listener.py > /tmp/listener.log 2>&1
切换到工作目录并从那里执行脚本,然后您可以查看就地创建的文件。
【讨论】:
什么是 2>&1 是什么意思? @MohideenibnMohammed 将错误消息 (stderr
) 重定向到可见命令行 (stdout
)
如果你使用相对路径,这个答案是你应该使用的答案。
这个答案可以解决这个问题吗:***.com/questions/65586171/… ?以上是关于通过 crontab 执行 Python 脚本的主要内容,如果未能解决你的问题,请参考以下文章
在OS X El Capitan上通过crontab启动python脚本
关于Python脚本通过crontab调度的时候报错UnicodeEncodeError: ‘ascii’ codec can’t encode characters in positi的解决方案