有时候手工执行Python脚本跑的好好的,但是部署到Linux的crontab中后,就会遇到一些问题,最近终于有空整理一下这方面的内容,其实也是自己也踩了一些别人踩过的坑!这里仅仅列举个人遇到的一些小问题,经验和精力问题,不能面面俱到,仅总结一下自己遇到的这些问题。

环境变量问题

 

cron中的环境变量和系统的环境变量是不一样的,我们可以通过设置定时脚本将cron中的环境变量打印出来,然后一对比,你就能发现差异

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

如果你Python脚本中要获取环境变量的话,那么部署到Crontab作业后就要小心了,很有可能手工运行脚本是正常的,但是部署到Crontab后运行就不正常了,如下所示,我们构造这样一个测试脚本crontab_env_test.py

  1. #!/usr/bin/python

  1. # -*- coding: utf-8 -*-

  1.  

  1. import logging

  1. import os.path

  1. import os

  1. import base64

  1.  

  1.  

  1.  

  1. # 第一步,创建一个logger

  1. logger = logging.getLogger()

  1. logger.setLevel(logging.DEBUG)  # Log等级开关

  1. # 第二步,创建一个handler,用于写入日志文件

  1. log_path = '/home/konglb/logs/'

  1. log_name = log_path + 'kerry_test.log'

  1. logfile = log_name

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

  1. file_handler.setLevel(logging.ERROR)  # 输出到file的log等级的开关

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

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

  1. file_handler.setFormatter(formatter)

  1. # 第四步,将handler添加到logger里面

  1. logger.addHandler(file_handler)

  1. # 如果需要同時需要在終端上輸出,定義一個streamHandler

  1. print_handler = logging.StreamHandler()  # 往屏幕上输出

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

  1. logger.addHandler(print_handler)

  1.  

  1.  

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

  1. print(db_user)

  1. logger.error(db_user)

如下所示,手工执行该脚本,就会往/home/konglb/logs/kerry_test.log中写入环境变量my_env的值(/etc/profile中设置了export my_env=kerry )

# /usr/local/bin/python3.6 /home/konglb/python/crontab_env_test.py

kerry

2019-08-20 20:20:18,293 - crontab_env_test.py[line:30] - ERROR: kerry

然后我们配置crontab后,如下所示,通过刷新日志观察其获取环境变量my_env的值

# crontab -l

*/1 * * * *  /usr/local/bin/python3.6 /home/konglb/python/crontab_env_test.py

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

  1. # tail -60f kerry_test.log

  1. 2019-08-20 20:20:18,293 - crontab_env_test.py[line:30] - ERROR: kerry

  1. 2019-08-20 20:22:02,337 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:23:01,533 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:24:01,682 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:25:01,832 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:26:01,103 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:27:01,243 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:28:01,397 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:29:01,543 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:30:01,680 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:31:01,998 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:32:01,223 - crontab_env_test.py[line:30] - ERROR: None

  1. 2019-08-20 20:33:01,369 - crontab_env_test.py[line:30] - ERROR: Non

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

*/1 * * * * source /etc/profile && /usr/local/bin/python3.6 /home/konglb/python/crontab_env_test.py

还有一种方案,就是使用shell包裹Python脚本,如下所示:

  1. # more kerry.sh

  1.  

  1. #!/bin/bash

  1.  

  1. source /etc/profile

  1.  

  1. /usr/local/bin/python3.6 /home/konglb/python/crontab_env_test.py

*/1 * * * *    /home/konglb/python/kerry.sh

 

相对路径问题

 

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

  1. #!/usr/bin/python

  1. # -*- coding: utf-8 -*-

  1.  

  1. import logging

  1. import os.path

  1. import os

  1. import base64

  1.  

  1.  

  1.  

  1. # 第一步,创建一个logger

  1. logger = logging.getLogger()

  1. logger.setLevel(logging.DEBUG)  # Log等级开关

  1. # 第二步,创建一个handler,用于写入日志文件

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

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

  1. log_name = log_path + 'kerry_test.log'

  1. logfile = log_name

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

  1. file_handler.setLevel(logging.ERROR)  # 输出到file的log等级的开关

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

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

  1. file_handler.setFormatter(formatter)

  1. # 第四步,将handler添加到logger里面

  1. logger.addHandler(file_handler)

  1. # 如果需要同時需要在終端上輸出,定義一個streamHandler

  1. print_handler = logging.StreamHandler()  # 往屏幕上输出

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

  1. logger.addHandler(print_handler)

  1.  

  1.  

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

  1. print(db_user)

  1. logger.error(db_user)

其实切换到其它路径后,手工执行该脚本也会报错误,因为相对路径的设置,导致一些逻辑错误出现,如下所示,所以如果要部署为Crontab作业的Python脚本,最好使用绝对路径,避免出现这个问题。

  1. # pwd

  1. /root

  1. # /usr/local/bin/python3.6 /home/konglb/python/crontab_env_test.py

  1. Traceback (most recent call last):

  1.   File "/home/konglb/python/crontab_env_test.py", line 19, in <module>

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

  1.   File "/usr/local/lib/python3.6/logging/__init__.py", line 1031, in __init__

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

  1.   File "/usr/local/lib/python3.6/logging/__init__.py", line 1060, in _open

  1.     return open(self.baseFilename, self.mode, encoding=self.encoding)

  1. FileNotFoundError: [Errno 2] No such file or directory: '//logs/kerry_test.log'

另外,像密码过期导致crontab不执行作业(Linux账号密码过期会导致crontab作业不能执行)这样的案例也遇到过,不过这个与Python脚本无关系,如果遇到相关问题,可以从Why-Cronjob-Not-Work这篇文章介绍的这几个方面去思考、分析判断。

 

 

参考资料

https://www.tony-yin.site/2018/10/29/Why-Crontab-Not-Work/

crontab中部署Python脚本注意事项的更多相关文章

  1. mac上使用crontab周期性执行python脚本

    这个月买了本书<Linux系统命令及Shell脚本实践指南>, 看到了一个周期性执行任务cron.顿时产生一个想法: mac上有这种机制么? 加上自己也在15年下半年也学了点python脚 ...

  2. C++中调用Python脚本

    C++中调用Python脚本的意义就不讲了,至少你可以把它当成文本形式的动态链接库, 需要的时候还可以改一改,只要不改变接口, C++的程序一旦编译好了,再改就没那么方便了 先看Python的代码 代 ...

  3. Delphi中使用python脚本读取Excel数据

    Delphi中使用python脚本读取Excel数据2007-10-18 17:28:22标签:Delphi Excel python原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...

  4. nginx tomcat 自动部署python脚本【转】

    #!/usr/bin/env python #--coding:utf8-- import sys,subprocess,os,datetime,paramiko,re local_path='/ho ...

  5. Linux系统crontab定时调度Python脚本

    Linux系统crontab定时调度Python脚本 一.Python脚本随Linux开机自动运行 #Python脚本:/home/edgar/auto.py #用root权限编辑以下文件:/etc/ ...

  6. C++中调用Python脚本(转载)

    转载▼ 标签: 杂谈 C++中调用Python脚本的意义就不讲了,至少你可以把它当成文本形式的动态链接库,需要的时候还可以改一改,只要不改变接口, C++的程序一旦编译好了,再改就没那么方便了先看Py ...

  7. 使用shell程序备份crontab中的.sh脚本文件

    需求 线上环境有一些定时脚本(用crontab -l可查看当前用户的),有时我们可能会改这些定时任务的脚本内容.为避免改错无后悔药,需用shell实现一个程序,定时备份crontab中的.sh脚本文件 ...

  8. crontab定时运行python脚本访问MySQL遇到问题

    最近写了一个python脚本来定时备份MySQL数据库.具体实现如下: 1)python脚本中使用os.system("mysqldump -h127.0.0.1 -uroot -ppass ...

  9. crontab中运行python程序出错,提示ImportError: No module named解决全过程

    将一个python脚本放入crontab执行时,提示如下错:ImportError: No module named hashlib但是在shell中直接执行时没有任何问题,google之后,得到线索 ...

随机推荐

  1. redis服务打不开--解决办法

    D:\>redis-server[11896] 04 Dec 19:20:05.122 # Warning: no config file specified, using the defaul ...

  2. Video/audio标签的一些基础使用心得

    常用方法 .play():用于音频视频的播放 .pause():用于音频视频的暂停 常用属性 <audio src="Batmobile Battle Mode Reveal Musi ...

  3. JDBC访问数据库的基本步骤

    加载驱动 通过DriverManager对象获取连接对象Connection 通过连接对象获取会话 通过会话进行数据的增删改查,封装对象 关闭资源

  4. SDI接口基于FPGA GTP实现

    SDI采集和显示,基于xilinx 7系列器件进行实现,注意事项有如下几点: 1,如果多路SDI共用一个GTP Quad,或是SDI和PCIE在一个GTP Quad,时钟资源应该进行共享,既GTP c ...

  5. MAC 上的Phantomjs的安装和配置

    1.下载 http://phantomjs.org/download.html 选择mac版本下载 2.下载完成后,解压缩,然后放到自己的一个目录下面 例如:/usr/local/Phantomjs/ ...

  6. 了解ajax基本爬取方式

    '''爬去豆瓣电影数据了解ajax的基本爬去方式 ''' from urllib import requestimport jsonimport ssl url = "https://mov ...

  7. 分享:JS视频在线视频教程

    作者说明 (1)JS说明 JS是非常重要的一门语言,但是,我们对JS的认识似乎仍然停留在“hello word”或者“alert”的观念上.其实,JS发展到现在已经非常的成熟,功能也非常的强大,因此, ...

  8. drf框架安装配置及其功能概述

    0902自我总结 drf框架安装配置及其功能概述 一.安装 pip3 install djangorestframework 二.配置 # 注册drf app NSTALLED_APPS = [ # ...

  9. VMware15.5版本下安装Windows_Server_2008_R2

    一.新建虚拟机 第一步:打开VMware15.5虚拟机,在欢迎界面点击新建虚拟机: 第二步:选择典型(推荐)选项-->适用于新手,单击下一步: 第三步:选定最后一项稍后安装操作系统,单击下一步: ...

  10. 如何正确的在 Android 上使用协程 ?

    前言 你还记得是哪一年的 Google IO 正式宣布 Kotlin 成为 Android 一级开发语言吗?是 Google IO 2017 .如今两年时间过去了,站在一名 Android 开发者的角 ...