python2 SimpleHTTPServer 日志输出文件为空

问题描述

在自己的云服务器上用python开了一个HTTP服务,便于下载各种实用工具,下载日志重定向到http.log文件中。执行命令如下:

nohup python -m SimpleHTTPServer 2>&1 >/home/ubuntu/download/http.log &

但是,突然发现http.log是空的。多次重启服务、删除http.log再重启服务,都无济于事,http.log依然是空的。

问题分析

1. 查看重定向

查看进程打开的文件描述符,排查重定向是否有问题:

root@VM-0-15-ubuntu:~/download# ps -ef | grep python
root       729     1  0 10:57 ?        00:00:00 python -m SimpleHTTPServer
root       875     1  0 Apr05 ?        00:00:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root       927     1  0 Apr05 ?        00:00:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root      6298  4327  0 11:27 pts/7    00:00:00 grep --color=auto python
root@VM-0-15-ubuntu:~/download#
root@VM-0-15-ubuntu:~/download# ls /proc/729/fd -lh
total 0
lr-x------ 1 root root 64 Apr 17 11:28 0 -> /dev/null
l-wx------ 1 root root 64 Apr 17 11:28 1 -> /home/ubuntu/download/http.log
lrwx------ 1 root root 64 Apr 17 11:28 2 -> '/tmp/#409843 (deleted)'
lrwx------ 1 root root 64 Apr 17 11:28 3 -> 'socket:[15759028]'
lr-x------ 1 root root 64 Apr 17 11:28 7 -> /dev/urandom

1 -> /home/ubuntu/download/http.log 表示标准输出重定向到文件/home/ubuntu/download/http.log。看来,重定向没问题。

2. 查看python输出
上网查阅资料发现:

python的标准输入和标准输出写到了缓冲中,如果日志为空,说明输出没有被刷新(flush)到文件中。
执行python程序时,添加 -u选项 或者 指定 PYTHONUNBUFFERED=x,可以指定输出不写到缓存。
root@VM-0-15-ubuntu:~# python --help
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options and arguments (and corresponding environment variables):
-b     : issue warnings about comparing bytearray with unicode
         (-bb: issue errors)
-B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x
-c cmd : program passed in as string (terminates option list)
-d     : debug output from parser; also PYTHONDEBUG=x
-E     : ignore PYTHON* environment variables (such as PYTHONPATH)
-h     : print this help message and exit (also --help)
-i     : inspect interactively after running script; forces a prompt even
         if stdin does not appear to be a terminal; also PYTHONINSPECT=x
-m mod : run library module as a script (terminates option list)
-O     : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x
-OO    : remove doc-strings in addition to the -O optimizations
-R     : use a pseudo-random salt to make hash() values of various types be
         unpredictable between separate invocations of the interpreter, as
         a defense against denial-of-service attacks
-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew
-s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE
-S     : don't imply 'import site' on initialization
-t     : issue warnings about inconsistent tab usage (-tt: issue errors)
-u     : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x
         see man page for details on internal buffering relating to '-u'
-v     : verbose (trace import statements); also PYTHONVERBOSE=x
         can be supplied multiple times to increase verbosity
-V     : print the Python version number and exit (also --version)
-W arg : warning control; arg is action:message:category:module:lineno
         also PYTHONWARNINGS=arg
-x     : skip first line of source, allowing use of non-Unix forms of #!cmd
-3     : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix
file   : program read from script file
-      : program read from stdin (default; interactive mode if a tty)
arg ...: arguments passed to program in sys.argv[1:]

Other environment variables:
PYTHONSTARTUP: file executed on interactive startup (no default)
PYTHONPATH   : ':'-separated list of directories prefixed to the
               default module search path.  The result is sys.path.
PYTHONHOME   : alternate <prefix> directory (or <prefix>:<exec_prefix>).
               The default module search path uses <prefix>/pythonX.X.
PYTHONCASEOK : ignore case in 'import' statements (Windows).
PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.
PYTHONHASHSEED: if this variable is set to 'random', the effect is the same
   as specifying the -R option: a random value is used to seed the hashes of
   str, bytes and datetime objects.  It can also be set to an integer
   in the range [0,4294967295] to get hash values with a predictable seed.
root@VM-0-15-ubuntu:~#

于是,我添加了 -u选项:

nohup python -u -m SimpleHTTPServer 2>&1 >/home/ubuntu/download/http.log &

这次,http.log里有日志了:

Serving HTTP on 0.0.0.0 port 8000 ...

但是,日志只打了这一句,后面通过浏览器下载文件,日志都不再更新。。。

最后,改变重定向方式,使用 &> 重定向:

nohup python -u -m SimpleHTTPServer &> /home/ubuntu/download/http.log &

如此,日志打印就正常了:

root@VM-0-15-ubuntu:~/download# tail -f http.log
Serving HTTP on 0.0.0.0 port 8000 ...
61.48.208.128 - - [17/Apr/2022 12:27:26] "GET / HTTP/1.1" 200 -
61.48.208.128 - - [17/Apr/2022 12:27:27] "GET / HTTP/1.1" 200 -
61.48.208.128 - - [17/Apr/2022 12:27:40] "GET /SecureCRT%206.5.0.zip HTTP/1.1" 200 -

&> 重启服务后日志会清空,改成 &>> 日志就能追加了:

nohup python -u -m SimpleHTTPServer &>>  /home/ubuntu/download/http.log &

(完)

参考文章:

  1. nohup不能及时打印python print日志
  2. Python http server 与 nohup 使用时无法打印日志的问题
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值