![](/img/trans.png)
[英]open and write commands in command prompt from subprocess.Popen python in Windows 10
[英]Edit subprocess.Popen( linux command ) on Windows10
我正在研究与 Superpoint 的图像匹配( https://github.com/rpautrat/SuperPoint )。
我试图运行写在用法区的代码。 不幸的是,我在 Windows10 和 Superpoint 上使用此代码为 linux 所以我得到了很多错误...... :(
特别是, https://github.com/rpautrat/SuperPoint/blob/master/superpoint/utils/stdout_capturing.py对我造成严重错误。
subprocess.Popen 中有一部分用于使用文件描述符写入日志文件。 我想获得与从 linux 操作系统获得的结果相同的日志文件结果。
代码如下....而且我认为tee命令在 Windows 上不起作用,这就是这部分导致错误的原因。
我希望编辑这部分以运行整个代码以研究 Superpoint。
请让我知道此文件描述符在 Windows10 问题上的解决方案。
非常感谢您的好意帮助!
#!/usr/bin/env python
# coding=utf-8
from __future__ import division, print_function, unicode_literals
import os
import sys
import subprocess
from threading import Timer
from contextlib import contextmanager
'''
Based on sacred/stdout_capturing.py in project Sacred
https://github.com/IDSIA/sacred
'''
def flush():
"""Try to flush all stdio buffers, both from python and from C."""
try:
sys.stdout.flush()
sys.stderr.flush()
except (AttributeError, ValueError, IOError):
pass # unsupported
# Duplicate stdout and stderr to a file. Inspired by:
# http://eli.thegreenplace.net/2015/redirecting-all-kinds-of-stdout-in-python/
# http://stackoverflow.com/a/651718/1388435
# http://stackoverflow.com/a/22434262/1388435
@contextmanager
def capture_outputs(filename):
"""Duplicate stdout and stderr to a file on the file descriptor level."""
# with NamedTemporaryFile(mode='w+') as target:
with open(filename, 'a+') as target:
original_stdout_fd = 1
original_stderr_fd = 2
target_fd = target.fileno()
# Save a copy of the original stdout and stderr file descriptors
saved_stdout_fd = os.dup(original_stdout_fd)
saved_stderr_fd = os.dup(original_stderr_fd)
tee_stdout = subprocess.Popen(
['tee', '-a', '/dev/stderr'], start_new_session=True,
stdin=subprocess.PIPE, stderr=target_fd, stdout=1)
tee_stderr = subprocess.Popen(
['tee', '-a', '/dev/stderr'], start_new_session=True,
stdin=subprocess.PIPE, stderr=target_fd, stdout=2)
flush()
os.dup2(tee_stdout.stdin.fileno(), original_stdout_fd)
os.dup2(tee_stderr.stdin.fileno(), original_stderr_fd)
try:
yield
finally:
flush()
# then redirect stdout back to the saved fd
tee_stdout.stdin.close()
tee_stderr.stdin.close()
# restore original fds
os.dup2(saved_stdout_fd, original_stdout_fd)
os.dup2(saved_stderr_fd, original_stderr_fd)
# wait for completion of the tee processes with timeout
# implemented using a timer because timeout support is py3 only
def kill_tees():
tee_stdout.kill()
tee_stderr.kill()
tee_timer = Timer(1, kill_tees)
try:
tee_timer.start()
tee_stdout.wait()
tee_stderr.wait()
finally:
tee_timer.cancel()
os.close(saved_stdout_fd)
os.close(saved_stderr_fd)
我会用这个实现 go: https://stackoverflow.com/a/17942748/5430833
首先,'tee' 是一个 linux 实用程序,除非你安装了一些端口。 /dev/stderr 也是错误 output stream 的 unix 描述符。 根据这个答案: cmd.exe 等效于 /dev/stdout,以“作为文件”写入标准输出,没有与 windows 等效的描述符。
如果您希望您的解决方案具有可移植性,我建议您坚持使用 python 并避免使用 Popen,除非您确定您正在启动的进程在两个平台上都有效。
编辑:好的,请原谅我,因为我没有仔细阅读这个问题。 因此,您需要某种“守护程序”进程来捕获所有标准输出和标准错误。 如果您可以在控制台中没有 output 的情况下生活,我会用一个简单的解决方案 go :注释掉“capture_outputs”内容并在您的应用程序启动时(您的测试文件或某种main ,在任何 SuperPoint 代码执行之前)重定向流:
sys.stdout = open('out.dat', 'w')
在出口的某个地方:
sys.stdout.close()
您可以使用 ContextManager 包装您的逻辑,以便在某些内部异常文件的情况下正确关闭。
我相信您也可以在“capture_outputs”中进行重定向,但我建议保持简单,除非我们确定它有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.