前情提要:我需要在服务器上运行一个python任务,需要每天生成虚拟的数据,一开始我只写了生成的A.py文件,后来因为这是一个定时任务,所以又建了一个定时调用A的B.py文件。
具体操作流程
首先我尝试了Linux系统的nohup命令,想利用它一直在后台运行B文件。但是它存在一个问题,就是当我关闭命令窗口,nohup运行的定时任务也就停了,后面也找了许多说如何使它保持运行的方法,但一直都不见效。
然后我经理告诉我可以用Linux的crontab命令,这个命令可以直接设置“定时+运行指令”。我先上菜鸟教程看了一下命令的用法,基本熟悉了一下觉得确实很方便。
直接上手,首先查看crontab里有没有运行的命令:
crontab -l
空空如也,我可以放心大胆的操作了。进入crontab的编辑界面(其实前面的crontab -l操作就是把编辑界面的内容展示出来):
crontab -e
如果从来没有用过此命令,初始化的编辑界面会显示一大堆的说明内容,我嫌他碍事及直接删掉了,所以这部分没有截图。在空空的编辑界面写上一个测试定时任务:
* * * * * echo "11" >> /tmp/test
这些*的意思可以在菜鸟里看到,我就不赘述了。这个句子的意思是每一秒都执行echo '11' >> /tmp/test
,将11写进根目录下tmp文件夹的test文件。
接下来要保存这个编辑,怎么操作呢?下面有一堆的按键展示:
其它不用看了,直接Ctrl+O(字母):
眼花缭乱是吧,文件名咱就不要改啦,按下Ctrl+M:
按下Ctrl+X完美退场,这时候会出现:
就说明保存成功,要是不放心可以按第一条指令查看crontab的运行命令,也可以直接去查看/tmp/test的内容。
进入正题
中间出现了挺多问题的,我先把我最终的处理方法说一下,遇到的问题在后面讲。
首先,我的crontab编辑界面里是一条这样的命令:
0 9 * * * sh /home/**/**/**/run.sh >> /home/**/**/**/run.log
它表示每天9:00运行 /home/**/**/**/
路径下的run.sh
脚本,脚本的具体内容是:
#!/bin/sh
export PATH=/home/**/**/**/venv/bin/:$PATH
source /home/**/**/**/venv/bin/activate
cd /home/**/**/** && python A.py
脚本中的第一行是不能省略的,省略之后我的不运行。
我遇到的问题
1. A.py的运行需要在我创建的虚拟环境下
这是遇到的最大的问题,我花了一上午时间弄它。前期我已经配好了该文件所要求的虚拟环境,存储在/home/**/**/**/
路径下,一开始我的run.sh
脚本写的是:
#!/bin/sh
source /home/**/**/**/venv/bin/activate
cd /home/**/**/** && python A.py
但理应创建的文件却没有创建,我在想一定是没有运行py文件,但我的py文件在服务器上手动跑过几次都没有问题,所以我有理由认为是环境没有弄好。为了检验是否是环境的问题,我先尝试着打印我目前的环境,暂时不执行py文件,所以先修改crontab
的命令:
crontab -e
* * * * * sh /home/**/**/**/run.sh
依次操作Ctrl+O,Ctrl+M,Ctrl+X保存crontab。
再修改我的run.sh
脚本为:
#!/bin/sh
source /home/**/**/**/venv/bin/activate
echo $PATH >> /tmp/test
显示的$PATH
是:
/home/**/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
这时我直接在终端查看当前没有激活虚拟环境的环境变量:
echo $PATH
展示的结果与上面的环境变量一致,这时我们能够确定是因为环境变量的原因导致py文件无法运行。于是我打算先激活虚拟环境后看看环境变量:
source /home/**/**/**/venv/bin/activate
echo $PATH
终端展示:
/home/**/**/**/venv/bin:/home/**/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
经过对比可知,激活虚拟环境后的环境变量和激活之前的相比,前面多出了/home/**/**/**/venv/bin:
这部分。所以,run.sh
脚本部分增加了export PATH=/home/**/**/**/venv/bin/:$PATH
。
2. python /home/**/**/**/A.py
跑不起来
这部分很好解决,当我发现这样跑不起来时,我就换了一种写法,cd /home/**/**/** && python A.py
先进入文件所在位置再执行命令,虽然不知道是什么原因,但是成功执行了。
3. 不会用命令行读改保存文件内容
这是终端命令行使用的基础,那谁叫我是小白呢,谁都是从零开始的嘛!我用的都是vim
命令
vim run.sh
就可以直接在终端界面内展示文件run.sh
内容了,之后的操作:
- 按A可以修改里面的内容
- 按Esc退出编辑的状态
- 在非编辑状态下输入
:wq
(终端界面最下方会显示)保存退出 - 在非编辑状态下输入
:q
(终端界面最下方会显示)直接退出