Loading [MathJax]/jax/output/CommonHTML/config.js
社区首页 >问答首页 >subprocess.Popen通信()写入控制台,但不写入日志文件

subprocess.Popen通信()写入控制台,但不写入日志文件
EN

Stack Overflow用户
提问于 2017-12-27 15:08:58
回答 2查看 3.7K关注 0票数 1

Python脚本中有下面一行代码,它在原始脚本中运行单独的Python脚本:

代码语言:javascript
代码运行次数:0
复制
subprocess.Popen("'/MyExternalPythonScript.py' " + theArgumentToPassToPythonScript, shell=True).communicate()

使用上面的行,在单独的Python文件中找到的任何print()语句都会出现在主Python脚本的控制台中。

但是,这些语句是,而不是脚本写入的.txt文件日志中所反映的

有谁知道如何修复这个问题,以便.txt文件准确地反映主Python脚本的真正控制台文本?

这是我用来将控制台实时保存为一个方法文件的.txt:

代码语言:javascript
代码运行次数:0
复制
import sys
class Logger(object):
    def __init__(self):
        self.terminal = sys.stdout
        self.log = open("/ScriptLog.txt", "w", 0)
    def write(self, message):
        self.terminal.write(message)
        self.log.write(message)


sys.stdout = Logger()

我不一定喜欢这种方法。我对任何一种方法都感兴趣,这将实现我所详述的目标。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-27 16:45:16

请记住,subprocess生成了一个新的进程,并不真正与父进程进行通信(它们几乎是独立的实体)。尽管有其名称,communicate方法只是从父进程向子进程发送/接收数据的一种方式(例如,模拟用户在终端上输入某些内容)。

为了知道在哪里写入输出,子进程使用数字(文件标识符或文件号)。当子进程生成一个进程时,子进程只知道标准输出是O.S.中标识为7的文件(可以说是一个数字),但差不多就是这样。子进程将独立地查询操作系统,比如“嘿!7号文件是什么?给我,我有东西要写。”(在这里了解C fork所做的非常有用)

基本上,生成的子进程不理解您的Logger类。它只是知道它必须将它的内容写到一个文件中:一个在O.S中唯一标识的文件,它有一个数字,并且除非另有规定,这个数字对应于标准输出的文件描述符(但正如下面第2例所解释的,如果您愿意,可以更改它)。

所以你有几个“解决方案”..。

  1. 克隆(T形三通 stdout到一个文件,所以当某些东西被写到stdout时,操作系统也会将它写到您的文件中(这实际上与Python无关).(与操作系统有关): 导入os导入子进程file_log = os.path.join(tempfile.gettempdir(),'foo.txt') p= subprocess.Popen("python ./run_omething.py tee %s“% file_log,shell=True) p.wait()
  2. 选择是使用每个终端的函数将其写入终端还是将写入文件。例如,只写入文件: 导入os导入子进程file_log = os.path.join(tempfile.gettempdir(),'foo.txt'),打开(file_log,'w')作为f: P= subprocess.Popen("python ./run_omething.py“,shell=True,stdout=f.fileno() p.wait() )
  3. 我个人认为“更安全”的地方(我觉得不适合覆盖sys.stdout):只需让命令运行并将其输出存储到变量中,然后稍后(在父进程中)获取它: 导入os导入子进程p= subprocess.Popen("python ./run_omething.py“,shell=True,stdout=subprocess.PIPE) p.wait() p.wait() contents = p.stdout.read() #--不管Subprocess的输出现在存储在'contents‘中,让我们把它写到文件中: file_log = os.path.join(tempfile.gettempdir(),'foo.txt'),打开(file_log,'w')作为f: f.write(内容) 这样,您还可以在代码中的某个位置执行一个print(contents),以便向终端输出任何子进程“说”的内容。

例如,脚本“./run_omething.py”就是这样的:

代码语言:javascript
代码运行次数:0
复制
print("Foo1")
print("Foo2")
print("Foo3")
票数 0
EN

Stack Overflow用户

发布于 2017-12-27 15:58:57

你真的需要subprocess.Popencommunicate()方法吗?看起来你只是想要输出。这就是subprocess.check_output()的目的。

如果您使用它,您可以使用内置的日志记录模块"tee"-ing输出流到多个目的地。

代码语言:javascript
代码运行次数:0
复制
import logging
import subprocess
import sys

EXTERNAL_SCRIPT_PATH = '/path/to/talker.py'
LOG_FILE_PATH = '/path/to/debug.log'

logger = logging.getLogger('')
logger.setLevel(logging.INFO)

# Log to screen
console_logger = logging.StreamHandler(sys.stdout)
logger.addHandler(console_logger)

# Log to file
file_logger = logging.FileHandler(LOG_FILE_PATH)
logger.addHandler(file_logger)

# Driver script output
logger.info('Calling external script')

# External script output
logger.info(
    subprocess.check_output(EXTERNAL_SCRIPT_PATH, shell=True)
)

# More driver script output
logger.info('Finished calling external script')

和往常一样,小心使用shell=True。如果您可以将调用写为subprocess.check_output(['/path/to/script.py', 'arg1', 'arg2']),请这样做!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47999670

复制
相关文章
vue获取当前视图组件对象
想在console中调试查看vue对象的数据情况,奈何没有入口,全局的vue对象可以挂出来,但是没法定位到具体的视图对象。
shirishiyue
2019/06/29
3.5K0
Angular2 组件的使用
3.在 @Component 中 ,设置selector、template 和 styles 等元数据
用户1437675
2018/08/20
1.5K0
Angular的12个经典问题,看看你能答对几个?(文末附带Angular测试)
Angular作为目前最为流行的前端框架,受到了前端开发者的普遍欢迎。不论是初学Angular的新手,还是有一定Angular开发经验的开发者,了解本文中的12个经典面试问题,都将会是一个深入了解和学习Angular 2的知识概念的绝佳途径。 在文中,我们将会接触到很多Angular 2的重要概念,并附扩展阅读资料和自查小测试,供大家评估自己对Angular的了解程度。 Angular 经典问题及扩展阅读 1.  请解释Angular 2应用程序的生命周期hooks是什么? Angular 2组件/指令具有
葡萄城控件
2018/01/10
17.4K0
Angular的12个经典问题,看看你能答对几个?(文末附带Angular测试)
js获取当前时间的方法_c获取当前时间毫秒
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/09
21.3K0
js获取当前时间的方法_c获取当前时间毫秒
🔥【Angular教程】路由入门
路由的概念在前端的框架中得到了广泛的应用,对于路由的感念不做阐述,路由的应用无外乎就是嵌套、传参,高级一些的功能如懒加载、预加载,再高级一些的如:路由守卫等。本篇我们就一起来看一看在Angular中如何使用路由。
前端小鑫同学
2022/12/25
4.4K0
🔥【Angular教程】路由入门
关于Vue3获取当前组件实例的 getCurrentInstance 方法的补充
上一篇文章:快速使用Vue3最新的15个常用API(1W5+字详解,建议收藏),我向大家介绍了关于Vue3常用的15个API的使用详情,帮助大家快速上手Vue3,也很高兴收到大家的支持,同样也有一些人提出了疑问,尤其是对于 如何获取当前组件实例 这个问题的讨论最为激烈,这里我们就对其进行一些补充
@零一
2021/01/29
9.8K0
python获取当前系统的日期_python怎么获取当前系统时间
python获取当前系统时间,包括年月日,时分秒,主要通过Python中的datetime模块来实现。
全栈程序员站长
2022/11/02
6.3K0
python获取当前系统的日期_python怎么获取当前系统时间
javascript获取当前系统时间代码_获取当前系统时间
大家好,又见面了,我是你们的朋友全栈君。 JavaScript 获取当前时间time 开发常用时间笔记 JS获取当前时间 Js获取当前日期时间及其它操作 ** 谨记要懂得经常在控制台输出结果 **
全栈程序员站长
2022/11/09
18.5K0
Angular2 组件(页面)之间如何传值
在Angular 2中,数据和事件变化检测从上到下发生从<b>父级到子级。</b>
用户1437675
2018/08/20
4K0
Angular2 组件(页面)之间如何传值
java获取当前时间到毫秒_java获取当前时间毫秒
()为获取当前系统时间,也可使用当前时间戳 获取时间戳三种方法执行效率比较: import java.util.Calendar; import java.util.Date; public class TimeTest { ……
全栈程序员站长
2022/10/04
7.2K0
Angular 从入坑到挖坑 - 路由守卫连连看
Angular 入坑记录的笔记第六篇,介绍 Angular 路由模块中关于路由守卫的相关知识点,了解常用到的路由守卫接口,知道如何通过实现路由守卫接口来实现特定的功能需求,以及实现对于特性模块的惰性加载
程序员宇说
2020/06/04
3.8K0
获取当前jvm数据
获取当前jvm数据 import java.io.InputStreamReader; import java.io.LineNumberReader; import java.lang.management.ManagementFactory; import org.apache.log4j.Logger; import com.sun.management.OperatingSystemMXBean; public class MonitorUtil { private static fi
JQ实验室
2022/02/14
1.8K0
python 获取当前时间
Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能。 每个时间戳都以自从1970年1月1日午夜(历元)经过了多长时间来表示。
用户7886150
2021/01/19
4.1K0
ViewPager获取当前显示的View[通俗易懂]
思路:根据vp.getCurrentItem一级vp的child数,可算出当前child在vp中的index。但是此时还不能直接用vp.getChildAt获取,因为getChildAt对应的index不一定 为vp中child实际的排列顺序(左右拖动时,打log即可验证)。此时可根据各child的x值重新排序,再用vp.getChildAt即可。
全栈程序员站长
2022/09/15
1.6K0
java获取当前学期
获取当期学期 NumUtils //继承NumberUtils类 public class NumUtils extends NumberUtils { //把string的数字转化成int public static int obj2int(Object obj) { if (obj != null) { return (int)(toDouble(obj.toString())); } return 0; } //把BigDecimal转成double,保留几位小数 publi
微醺
2019/08/14
1.6K0
Android 获取当前时间
在项目开发中,难免会遇到使用当前时间,比如实现网络请求上传报文、预约、日历等功能。
网罗开发
2021/01/29
4.1K0
js获取当前域名
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/112873.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/08
20.6K0
Blazor 获取当前的 Url 链接
在 Blazor 获取当前页面所在的 URL 链接可以通过 NavigationManager 类辅助获取,也可以通过此方法获取当前域名等信息
林德熙
2022/08/12
3.6K0
ViewPager 获取当前显示的Fragment
Viewpager 获取当前显示的fragment 使用 getSupportFragmentManager().findFragmentByTag()方法 Viewpager + FragmentPagerAdapter 情况下 才好使; FragmentPagerAdapter 有一个特点 凡是加载过的Fragment 都会被保留,既然Fragment不会被销毁,那我们就可以使用findFragmentByTag() 方法找到它;但问题是动态创建的话 tag的设置;我们知道动态加载时是可以设置tag的,
佛系编码
2018/05/22
3.7K0
mysql 获取当前的时间戳
三者基本没有区别,稍微一点的区别在于:NOW(),CURRENT_TIMESTAMP()都表示SQL开始执行的时间;SYSDATE()表示执行此SQL时的当前时间
全栈程序员站长
2022/11/10
8.2K0
mysql 获取当前的时间戳

相似问题

如何在SQL中自动增加空值

54

如何在SQL Server中自动增加插入

27

自动增加从数据库获得的VARCHAR值?

44

如何在SQL中增加文本值

12

自动增加SQL Azure配额

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档