由于项目的需要,现在需要通过一种方式,让Python程序能够在会话退出后继续在后台运行,并将屏幕的输出重定向到文件中去。
本文的示例代码已经上传到http://download.csdn.net/detail/mrbcy/9789067
参考资料
http://blog.csdn.net/loonger_leon/article/details/5764552
http://www.cnblogs.com/hester/p/5575658.html
测试程序
先写一个测试程序,用于输出日志和打印到控制台。
#-*- coding: utf-8 -*- import logging import time from logging.handlers import RotatingFileHandler def func(): init_log() while True: print "output to the console" logging.debug("output the debug log") logging.info("output the info log") time.sleep(3); def init_log(): logging.getLogger().setLevel(logging.DEBUG) console = logging.StreamHandler() console.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s') console.setFormatter(formatter) logging.getLogger().addHandler(console) # add log ratate Rthandler = RotatingFileHandler("backend_run.log",maxBytes=10 * 1024 * 1024,backupCount=100,encoding="gbk") Rthandler.setLevel(logging.INFO) # formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s') Rthandler.setFormatter(formatter) logging.getLogger().addHandler(Rthandler) if __name__ == '__main__': func()
后台启动Python脚本
可以使用下面的命令来启动上面的脚本,让Python在后台运行。
nohup python -u main.py > test.out 2>&1 &
来解释一下这几个命令的参数。这一段来自http://www.jb51.cc/article/p-tzoatpnr-bgw.html
其中 0、1、2分别代表如下含义: 0 – stdin (standard input) 1 – stdout (standard output) 2 – stderr (standard error) nohup python -u main.py > test.out 2>&1 & nohup+最后面的& 是让命令在后台执行 >out.log 是将信息输出到out.log日志中 2>&1 是将标准错误信息转变成标准输出,这样就可以将错误信息输出到out.log 日志里面来。
运行命令后,会返回一个pid。像下面这样:
[1] 9208
后续可以学习Hadoop它们,把pid存起来,到时候stop的时候就把它杀掉。
跟踪输出文件变化
为了验证脚本可以在后台继续运行,我们退出当前会话。然后重新连接一个Session,然后输入下面的命令来跟踪文件的输出:
tail -f test.out
output to the console 2017-03-21 20:15:02,632 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:02,632 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:05,635 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:05,636 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:08,637 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:08,638 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:11,640 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:11,642 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:14,647 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:14,647 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:17,653 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:17,654 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:20,655 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:20,656 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:23,661 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:23,661 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:26,665 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:26,666 main.py[line:12] INFO output the info log output to the console 2017-03-21 20:15:29,670 main.py[line:11] DEBUG output the debug log 2017-03-21 20:15:29,671 main.py[line:12] INFO output the info log
说明我们的脚本确实在后台持续运行。
结束程序
可以直接通过之前的那个pid杀掉脚本,或者可以通过下面的命令查找pid。
ps -ef | grep python
root 1659 1 0 17:40 ? 00:00:00 /usr/bin/python /usr/lib/python2.6/site-packages/ambari_agent/AmbariAgent.py start root 1921 1659 0 17:40 ? 00:00:48 /usr/bin/python /usr/lib/python2.6/site-packages/ambari_agent/main.py start user 8866 8187 0 20:03 ? 00:00:06 /usr/bin/python3 /usr/bin/update-manager --no-update --no-focus-on-map root 9208 8132 0 20:12 pts/16 00:00:00 python -u main.py root 9358 8132 0 20:17 pts/16 00:00:00 grep --color=auto python
可以看到我们的pid是9208,调用kill杀掉就可以了。
kill -9 9208
编写启动及停止脚本
启动脚本
#!/bin/sh pid=`ps -ef|grep "python -u main.py"| grep -v "grep"|awk '{print $2}'` if [ "$pid" != "" ] then echo "main.py already run,stop it first" kill -9 ${pid} fi echo "starting now..." nohup python -u main.py > test.out 2>&1 & pid=`ps -ef|grep "python -u main.py"| grep -v "grep"|awk '{print $2}'` echo ${pid} > pid.out echo "main.py started at pid: "${pid}
停止脚本
#!/bin/sh pid=`ps -ef|grep "python -u main.py"| grep -v "grep"|awk '{print $2}'` if [ "$pid" != "" ] then kill -9 ${pid} echo "stop main.py complete" else echo "main.py is not run,there's no need to stop it" fi