格雅百科

在crontab中部署Python脚本需要注意的事项

格雅百科
-->

有时候手动执行Python脚本运行得很好,但是部署到Linux crontab后,就会遇到一些问题。最近终于有时间整理一下这方面的内容。其实我也踩过别人的一些。太糟糕了!这里我只列出一些我遇到的小问题、经验和精力问题。它不可能是详尽无遗的。我只是总结一下我遇到的这些问题。

环境变量问题

cron中的环境变量与系统环境变量不同。我们可以通过设置定时器脚本将cron中的环境变量打印出来,然后对比一下就可以发现不同了

* * * * * env > /tmp/env.txt

如果您想在 Python 脚本中获取环境变量,则在部署到 Crontab 作业后应该小心。很有可能手动运行脚本是正常的,但是部署到Crontab后就无法正常运行了,如下所示,我们构建这样一个测试脚本 crontab_env_www.gyballet.com

#!/usr/bin/python

# -*- 编码:utf-8 -*-

导入日志记录

导入os.path

导入操作系统

导入base64

# 第一步是创建一个记录器

logger =logging.getLogger()

logger.setLevel(logging.DEBUG) # 日志级别开关

# 第二步是创建一个用于写入日志文件的处理程序

log_path = '/home/konglb/logs/'

log_name = log_path + 'kerry_test.log'

日志文件 = 日志名称

file_handler =logging.FileHandler(logfile, mode='a+')

file_handler.setLevel(logging.ERROR) # 切换到输出日志级别到文件

# 第三步定义handler的输出格式

formatter =logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")

file_handler.setFormatter(格式化程序)

# 第四步,将handler添加到logger中

logger.addHandler(file_handler)

# 如果需要同时在终端输出,定义一个streamHandler

print_handler =www.gyballet.comHandler() # 输出到屏幕

print_handler.setFormatter(formatter) #设置屏幕显示的格式

logger.addHandler(print_handler)

db_user=os.environ.get('my_env')

打印(db_user)

logger.error(db_user)

如下所示,如果手动执行脚本,环境变量my_env的值会被写入到/home/konglb/logs/kerry_test.log(export my_env=kerry是在/etc/profile中设置的)

# /usr/local/bin/python3.6 /home/konglb/python/crontab_env_www.gyballet.com

凯里

2019-08-20 20:20:18,293 - crontab_env_www.gyballet.com[行:30] - 错误:kerry

然后我们配置好crontab后,如下图,我们可以通过刷新日志来获取环境变量my_env的值

# crontab -l

*/1 * * * * /usr/local/bin/python3.6 /home/konglb/python/crontab_env_www.gyballet.com

如下图所示,你会看到Crontab中运行的Python脚本根本没有获取到环境变量my_env的值

# tail -60f kerry_test.log

2019-08-20 20:20:18,293 - crontab_env_www.gyballet.com[行:30] - 错误:kerry

2019-08-20 20:22:02,337 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:23:01,533 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:24:01,682 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:25:01,832 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:26:01,103 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:27:01,243 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:28:01,397 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:29:01,543 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:30:01,680 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:31:01,998 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:32:01,223 - crontab_env_www.gyballet.com[行:30] - 错误:无

2019-08-20 20:33:01,369 - crontab_env_www.gyballet.com[行:30] - 错误:非

那么如何解决这个问题,如下图,执行Python脚本时,获取/etc/profile中的系统变量(不同平台或环境有所不同)

*/1 * * * * 源 /etc/profile && /usr/local/bin/python3.6 /home/konglb/python/crontab_env_www.gyballet.com

另一种解决方案是使用 shell 来包装 Python 脚本,如下所示:

# 更多 www.gyballet.com

#!/bin/bash

源/etc/profile

/usr/local/bin/python3.6 /home/konglb/python/crontab_env_www.gyballet.com

*/1 * * * * /home/konglb/python/www.gyballet.com

相对路径问题

修改上面的脚本,使用相对路径,如下图,然后运行crontab作业时就会报错

#!/usr/bin/python

# -*- 编码:utf-8 -*-

导入日志记录

导入os.path

导入操作系统

导入base64

# 第一步是创建一个记录器

logger =logging.getLogger()

logger.setLevel(logging.DEBUG) # 日志级别开关

# 第二步是创建一个用于写入日志文件的处理程序

#log_path = '/home/konglb/logs/'

log_path = os.path.dirname(os.getcwd()) + '/logs/'

log_name = log_path + 'kerry_test.log'

日志文件 = 日志名称

file_handler =logging.FileHandler(logfile, mode='a+')

file_handler.setLevel(logging.ERROR) # 切换到输出日志级别到文件

# 第三步定义handler的输出格式

formatter =logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")

file_handler.setFormatter(格式化程序)

# 第四步,将handler添加到logger中

logger.addHandler(file_handler)

# 如果需要同时在终端输出,定义一个streamHandler

print_handler =www.gyballet.comHandler() # 输出到屏幕

print_handler.setFormatter(formatter) #设置屏幕显示的格式

logger.addHandler(print_handler)

db_user=os.environ.get('my_env')

打印(db_user)

logger.error(db_user)

其实切换到其他路径后,手动执行脚本也会报错。因为相对路径的设置,会出现一些逻辑错误,如下图。因此,如果要将Python脚本部署为Crontab作业,最好使用绝对路径来避免这个问题。

#密码

/根

# /usr/local/bin/python3.6 /home/konglb/python/crontab_env_www.gyballet.com

追溯(最近一次调用最后一次):

文件“/home/konglb/python/crontab_env_www.gyballet.com”,第 19 行,位于

File_handler =logging.FileHandler(logfile, mode='a+')

文件“/usr/local/lib/python3.6/logging/__init__.py”,第 1031 行,位于 __init__

StreamHandler.__init__(self, self._open())

文件“/usr/local/lib/python3.6/logging/__init__.py”,第 1060 行,位于 _open

返回 open(self.baseFilename, self.mode, 编码=self.encoding)

FileNotFoundError: [Errno 2] 没有这样的文件或目录: '//logs/kerry_test.log'

另外,还遇到过密码过期导致crontab作业无法执行(Linux账户密码过期会导致crontab作业无法执行)等情况。然而,这与Python脚本无关。如果遇到相关问题,可以参考Why -Cronjob-Not-Work 这篇文章介绍这几个方面来思考、分析和判断。

参考文献

https://www.gyballet.com/2018/10/29/Why-Crontab-Not-Work/

-->

发表评论 (已有0条评论)

还木有评论哦,快来抢沙发吧~