0%

running cronjob using crontab on ubuntu linux

crontab

syntax

sudo crontab -e
1
2
# every 5 minutes
*/5 * * * * /home/user/git/repo/python-demo/run.sh
  * * * * * command to be executed
  - - - - -
  | | | | |
  | | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
  | | | ------- Month (1 - 12)
  | | --------- Day of month (1 - 31)
  | ----------- Hour (0 - 23)
  ------------- Minute (0 - 59)

crontab FAQs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# (1) how to edit crontab file ?
sudo crontab -e
sudo crontab -l

# (2) how to enable crontab log
sudo vim /etc/rsyslog.d/50-default.conf
cron.* /var/log/cron.log

# restart rsyslog
sudo service rsyslog restart
# now we can see
tail -f /var/log/cron.log


# (3) how to run a crontab job and see ENVS
sudo crontab -e

* * * * * env > /home/kezunlin/env.log
# 由root用户生成
# -rw-r--r-- 1 root root 411 3月 17 17:37 /home/kezunlin/env.log

#结果如下
LC_TIME=zh_CN.UTF-8
#MYFB_ROOT=/home/kezunlin/git/repo/myproject/
#HOME=/root
#PYTHON_BIN=/home/kezunlin/anaconda3/bin/python
LC_MONETARY=zh_CN.UTF-8
LOGNAME=root
#PATH=/usr/bin:/bin
LC_ADDRESS=zh_CN.UTF-8
LANG=en_US.UTF-8
LC_TELEPHONE=zh_CN.UTF-8
LC_NAME=zh_CN.UTF-8
SHELL=/bin/sh
LC_MEASUREMENT=zh_CN.UTF-8
LC_IDENTIFICATION=zh_CN.UTF-8
PWD=/root
#PYTHONPATH=$PYHONPATH:$MYFB_ROOT../
LC_NUMERIC=zh_CN.UTF-8
LC_PAPER=zh_CN.UTF-8

# 可以看到,系统执行crontab job则只会加载默认的ENVS+ /etc/environment中的ENVS,不会设置任何用户ENVS
# 如果scripts中使用了来自.bashrc, .profile中的ENVs,肯定会导致导致scripts执行失败
# **方案**
# 将用户自定义ENVS放置在/etc/environment


# 其他示例
# crontab 中最好使用绝对路径 (不能使用~等, 可以使用$HOME, source需要用.代替)
* * * * * sleep 5s && echo "yo"
* * * * * env >> $HOME/env.log
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
*/5 * * * * /home/ubuntu/scripts/run5.sh


# (5) 既然crontab可以加载/etc/environment中的ENVS,那么可以在crontab中使用来自/etc/environment中的ENVS,比如
*/1 * * * * $MYFB_ROOT/scripts/run5.sh #OK 可以替换下面的路径
*/1 * * * * /home/ubuntu/project/scripts/run5.sh


# (6) crontab和手动运行scripts的区别
# A: 手动运行,开启terminal,除了加载系统/etc/environment中的ENVS,
# 还会加载当前user的.bashrc .profile文件,设置好ENVS,可以在scripts中使用
# B: 然而crontab则不会加载用户ENVS
# ***所以crontab执行的scripts中最好使用绝对路径,不要使用用户ENVS,否则执行失败***
# 或者将用户ENVS写入到/etc/environment中

crontab 终极方案

ENVS

vim /etc/environment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# vim /etc/environment (可以被crontab加载,.bashrc则不行) 
# ~/git会被crontab替换为/root/git/repo/myproject,所以使用/home/kezunlin代替

# (1) ubuntu 16.04
MYFB_ROOT=/home/kezunlin/git/repo/myproject/
PYTHONPATH=$PYHONPATH:$MYFB_ROOT../
PYTHON_BIN=/home/kezunlin/anaconda3/bin/python

# (2) WSL
MYFB_ROOT=/home/ubuntu/git/myproject/
PYTHONPATH=$PYHONPATH:$MYFB_ROOT../
PYTHON_BIN=/usr/bin/python3

# (3) cloud server
MYFB_ROOT=/home/ubuntu/git/myproject/
PYTHONPATH=$PYHONPATH:$MYFB_ROOT../
PYTHON_BIN=/usr/bin/python3

crontab -e

1
2
3
4
5
6
# scripts的路径可以使用来自/etc/environment的ENVS
# 可以统一各个不同平台的写法
# for ubuntu 16.04 / WSL / cloud server
* * * * * env > $MYFB_ROOT/scripts/env.log
*/5 * * * * $MYFB_ROOT/scripts/run5.sh
*/10 * * * * $MYFB_ROOT/scripts/run10.sh

Scripts

scripts/run5.sh

1
2
3
4
5
6
#!/bin/sh
. /etc/environment
# MYFB_ROOT PYTHONPATH PYTHON_BIN
#env > $MYFB_ROOT/env_test.log
cd $MYFB_ROOT # 代码中使用了.flag.txt必须cd到此目录
$PYTHON_BIN run5.py >> log/log5.txt

scripts/run10.sh

1
2
3
4
5
6
#!/bin/sh
. /etc/environment
##env > $MYFB_ROOT/env_test.log
# MYFB_ROOT PYTHONPATH PYTHON_BIN
cd $MYFB_ROOT # 代码中使用了.flag.txt必须cd到此目录
$PYTHON_BIN run10.py >> log/log10.txt

Reference

History

  • 2020/1/17: created.