如何将stdout重定向到Python中的任意文件?
当从ssh会话中启动长时间运行的Python脚本(例如,Web应用程序)并进行后台处理,并且ssh会话关闭时,应用程序将引发IOError并在尝试写入stdout时失败.我需要找到一种方法来将应用程序和模块输出到文件而不是stdout,以防止由于IOError导致的失败.目前,我使用nohup将输出重定向到一个文件,这就完成了工作,但是我想知道是否有办法在不使用nohup的情况下完成它,出于好奇.
我已经尝试了sys.stdout = open('somefile', 'w'),但这似乎并没有阻止一些外部模块仍然输出到终端(或者sys.stdout = ...线路根本没有发射).我知道它应该使用我测试过的简单脚本,但我还没有时间在Web应用程序上进行测试.
有没有办法让Python在没有包含像下面这样的函数调用的情况下使stdout静音?
原始破码:
from sys import stdout
from copy import copy
save_stdout = copy(stdout)
stdout = open('trash','w')
foo()
stdout = save_stdout
Run Code Online (Sandbox Code Playgroud)
编辑:更正了Alex Martelli的代码
import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout
Run Code Online (Sandbox Code Playgroud)
这种方式有效,但似乎非常低效.有有是一个更好的办法.有任何想法吗?
我不认为这是可能的,但我想自己处理来自argparse的异常.
例如:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help', required=True)
try:
args = parser.parse_args()
except:
do_something()
Run Code Online (Sandbox Code Playgroud)
当我运行它:
$ myapp.py
usage: myapp --foo foo
myapp: error: argument --foo is required
Run Code Online (Sandbox Code Playgroud)
但我希望它落入例外.
我正在使用Python的热门分析器:http://docs.python.org/2/library/hotshot.html
它显示了如何打印统计数据:
stats.print_stats(20)
Run Code Online (Sandbox Code Playgroud)
但是我怎么把它变成文件呢?我不知道如何获取信息,因此我可以使用write()将其写入文件.
编辑:
我喜欢与以这种方式打印时相同的易读性结果:
stats = hotshot.stats.load("stones.prof")
stats.strip_dirs()
stats.sort_stats('time', 'calls')
stats.print_stats(20)
Run Code Online (Sandbox Code Playgroud)
所以它看起来像这样:
ncalls tottime percall cumtime percall filename:lineno(function)
1 3.295 3.295 10.090 10.090 pystone.py:79(Proc0)
Run Code Online (Sandbox Code Playgroud)
(所以当我打开stones.prof时它看起来不像)
我的程序中有很多print函数(python 2.7).有什么方法可以添加几行然后所有输出都可以重定向到stderr?我想要的是python代码,但不是linux管道.
例如,我的程序如下:
print 'hello world'
Run Code Online (Sandbox Code Playgroud)
我想添加一些代码,如:
redirect_output_to_stderr()
print 'hello world'
Run Code Online (Sandbox Code Playgroud)
然后可以将所有输出重定向到stderr.
我知道print >> sys.stderr, 'hello world'可以实现我的目标,但是它能否阻止修改现有代码?
我可以这样沉默和恢复sys.stdout:
import sys
sys.stdout = None
print('hello') # does not write to stdout
sys.stdout = sys.__stdout__
print('hello') # writes to stdout
Run Code Online (Sandbox Code Playgroud)
我知道我最好使用contextlib.redirect_stdout它可能做类似的事情,但我的问题是:为什么上面的代码工作?
我已经假设python会调用类似的东西sys.stdout.write(),无论我替换sys.stdout它应该至少有一个write方法(例如io.StringIO).
在Pandas中有没有办法捕获通过设置error_bad_lines = False和warn_bad_lines = True产生的警告?例如以下脚本:
import pandas as pd
from StringIO import StringIO
data = StringIO("""a,b,c
1,2,3
4,5,6
6,7,8,9
1,2,5
3,4,5""")
pd.read_csv(data, warn_bad_lines=True, error_bad_lines=False)
Run Code Online (Sandbox Code Playgroud)
产生警告:
Skipping line 4: expected 3 fields, saw 4
Run Code Online (Sandbox Code Playgroud)
我想将此输出存储到字符串中,以便最终将其写入日志文件以跟踪正在跳过的记录.
我尝试使用警告模块,但似乎没有这种"警告"具有传统意义.我使用的是Python 2.7和Pandas 0.16.
任何帮助将不胜感激.
我有一个使用 git lib 的 python 代码。对于某些命令,git lib 会抛出异常(CommandError 异常)。问题是这个异常是从另一个线程抛出的。我确实尝试/例外并捕获了异常并做了一些解决方法。然而,另一个线程仍在打印异常错误消息。
这是git lib中的代码
def pump_stream(cmdline, name, stream, is_decode, handler):
try:
for line in stream:
if handler:
if is_decode:
line = line.decode(defenc)
handler(line)
except Exception as ex:
log.error("Pumping %r of cmd(%s) failed due to: %r", name, cmdline, ex)
raise CommandError(['<%s-pump>' % name] + cmdline, ex) from ex
finally:
stream.close()
Run Code Online (Sandbox Code Playgroud)
它创建这样的线程:
threads = []
for name, stream, handler in pumps:
t = threading.Thread(target=pump_stream,
args=(cmdline, name, stream, decode_streams, handler))
t.setDaemon(True)
t.start()
threads.append(t)
## FIXME: Why …Run Code Online (Sandbox Code Playgroud) 简短版本(如果你可以回答短版本它为我做的工作,其余的主要是为了其他有类似任务的人的利益):
在Windows的python中,我想创建2个文件对象,附加到同一个文件(它不必是硬盘上的实际文件),一个用于读取,一个用于写入,如果读取结束试图读取它永远不会得到EOF(它会阻止直到写入内容).我认为在linux中os.mkfifo()可以完成这项工作,但在Windows中它并不存在.可以做些什么?(我必须使用文件对象).
一些额外的细节:我有一个python模块(不是我写的)通过stdin和stdout(使用raw_input()和print)播放某个游戏.我也有一个Windows可执行文件,通过stdin和stdout播放相同的游戏.我想让他们一对一玩,并记录他们所有的沟通.
这是我可以编写的代码(该get_fifo()函数未实现,因为这是我不知道做的Windows):
class Pusher(Thread):
def __init__(self, source, dest, p1, name):
Thread.__init__(self)
self.source = source
self.dest = dest
self.name = name
self.p1 = p1
def run(self):
while (self.p1.poll()==None) and\
(not self.source.closed) and (not self.source.closed):
line = self.source.readline()
logging.info('%s: %s' % (self.name, line[:-1]))
self.dest.write(line)
self.dest.flush()
exe_to_pythonmodule_reader, exe_to_pythonmodule_writer =\
get_fifo()
pythonmodule_to_exe_reader, pythonmodule_to_exe_writer =\
get_fifo()
p1 = subprocess.Popen(exe, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
old_stdin = sys.stdin
old_stdout = sys.stdout
sys.stdin = exe_to_pythonmodule_reader
sys.stdout = pythonmodule_to_exe_writer
push1 = Pusher(p1.stdout, exe_to_pythonmodule_writer, p1, '1')
push2 …Run Code Online (Sandbox Code Playgroud) 如您所知,python smtplib具有调试级别.当我将其设置为真正的参数时,它将打印一些发送信息.
问题是,我尝试将调试信息记录到一个文件中,但它们只停留在我的cmd控制台上.如何记录它们?
像这样的信息:
connect: ('192.168.1.101', 25)
connect: (25, '192.168.1.101')
reply: '220 ESMTP on WinWebMail [3.8.1.3] ready. http://www.winwebmail.com\r\n'
reply: retcode (220); Msg: ESMTP on WinWebMail [3.8.1.3] ready. http://www.winw
ebmail.com
connect: ESMTP on WinWebMail [3.8.1.3] ready. http://www.winwebmail.com
send: 'ehlo [169.254.63.67]\r\n'
reply: '250-SIZE\r\n'
reply: '250 AUTH LOGIN\r\n'
reply: retcode (250); Msg: SIZE
AUTH LOGIN
bla bla bla bla........
Run Code Online (Sandbox Code Playgroud) 假设我们有以下虚拟函数:
import sys
def writeline(text, stream=sys.stdout):
stream.write(text + '\n')
with open('/path/to/file', 'w') as f:
# writes to /path/to/file
writeline('foo', f)
# writes to standard output
writeline('bar')
Run Code Online (Sandbox Code Playgroud)
鉴于 Python 在定义时计算函数的默认参数,设置sys.stdout为默认参数是否安全,或者可能会产生意想不到的副作用?
我试图管道以下命令的输出,/dev/null以便它不会为运行该程序的用户打印.
import os
os.system("ping -c 1 192.168.unknown.host > /dev/null")
Run Code Online (Sandbox Code Playgroud)
但我得到错误:
ping: unknown host 192.168.unknown.host
Run Code Online (Sandbox Code Playgroud)
问题是这个消息是由其他东西产生的stdout,可能stderr我可以很容易地将它重定向到/dev/null使用
ping -c 1 192.168.unknown.host >& /dev/null
Run Code Online (Sandbox Code Playgroud)
但是,当我在python中使用它时,我收到以下错误:
sh: 1: Syntax error: Bad fd number
Run Code Online (Sandbox Code Playgroud)
有可能解决这个问题吗?(我只是不希望打印这条消息).