Terminal 将python脚本中的shell命令输出保存到文本文件

Terminal 将python脚本中的shell命令输出保存到文本文件,terminal,python,Terminal,Python,我设法在python脚本中调用并使用terminal命令,它就在这个脚本中工作 但目前我正试图将此命令的“输出”结果保存到文本文件中,但出现了错误 这是我的初始代码,它在其中正确运行: import os os.system("someCmds --proj ARCH --all") 尝试将输出保存到文本文件时使用的代码: import os import sys sys.stdout=open("output.txt","w") command = os.system("someCmds -

我设法在python脚本中调用并使用terminal命令,它就在这个脚本中工作

但目前我正试图将此命令的“输出”结果保存到文本文件中,但出现了错误

这是我的初始代码,它在其中正确运行:

import os
os.system("someCmds --proj ARCH --all")
尝试将输出保存到文本文件时使用的代码:

import os
import sys
sys.stdout=open("output.txt","w")
command = os.system("someCmds --proj ARCH --all")
print command
sys.stdout.close()
但是,我得到了以下错误-
ValueError:对关闭的文件执行I/O操作


我确实关闭了文件,因为我在网上找到了这个。那么我错在哪里呢?

本文的Python编程部分更适合stackoverflow.com。但是,也有一个面向Unix的组件

每个进程都有三个著名的文件描述符。虽然它们的名称分别为stdin、stdout和stderr,但实际上它们的文件号是已知的,分别为0、1和2。要运行程序并捕获其stdout和file-number-1输出,必须将该进程的file-descriptor-1连接到文件或管道

在命令行shell中,有以下语法:

prog > file
在一个进程中运行程序
prog
,该进程的stdout连接到已移动到descriptor-slot-1的打开文件描述符。实际上,在系统调用级别执行所有操作是复杂的:

  • 打开文件。这将导致一个打开的文件描述符,其数量可能大于2,因为从0到2是您自己的stdin、stdout和stderr
  • 使用
    fork
    系统调用或其变体之一:这将克隆您自己
  • 在克隆中(但不是在原始中),将文件描述符从现在的位置移动到文件描述符1。然后关闭原始的编号较高的描述符(以及您已打开但不希望传递的任何其他描述符)
  • 使用
    exec
    调用系列中的一个来终止您自己(克隆),但在此过程中,用程序
    prog
    替换所有内容。这将维护所有打开的文件描述符,包括指向在步骤3中移动的文件或管道的描述符。一旦
    exec
    成功,您就不再存在,也无法执行任何操作。(如果
    exec
    失败,报告失败并退出。)
  • 回到原始(父)进程,等待克隆子进程执行然后完成,或者失败,或者发生任何情况
  • Python就是这样,在
    子流程
    模块中,这个多步骤序列为您打包,并带有奇特的错误检查。您可以使用
    subprocess.Popen
    ,而不是使用
    os.system
    。它设计用于处理管道,而管道实际上比文件更困难,因此,如果您真的想重定向到文件,而不是简单地通过管道读取程序的输出,那么您需要先打开文件,然后调用
    subprocess.Popen

    在任何情况下,更改Python进程的
    sys.stdout
    都没有帮助,因为
    sys.stdout
    是一种完全独立于底层文件描述符系统的Python数据结构。通过
    open
    ing一个Python流,您可以获得一个文件描述符(以及Python数据结构),但它不是file-descriptor-number-1。在克隆中,无论底层文件描述符编号是什么,都必须在
    fork
    调用之后移动到slot-1位置。即使使用
    subprocess.Popen
    ,Python将移动的唯一描述符post fork就是作为
    stdout=
    参数传递的描述符

    (子流程的
    Popen
    接受以下任何一项:

    • Python流:Python使用
      stream.fileno()
      获取描述符编号,或者
    • 整数:Python假定它表示一个打开的文件描述符,根据它是
      stdin=
      stdout=
      还是
      stderr=
      的参数,应该将其移动到fd 0、1或2
    • 特殊值
      subprocess.PIPE
      或对于
      stderr=
      subprocess.STDOUT
      :这些值告诉Python应该创建一个管道,或者为特殊的
      stderr=subprocess.STDOUT
      案例重新使用先前创建的STDOUT管道

    该库非常奇特,并且知道如何通过Python回溯报告到
    exec
    的故障,或者子级中发生的各种其他故障。它使用另一个辅助管道关闭exec来完成此操作。此管道上的EOF表示exec成功;否则,到达此额外管道的数据包括故障,已转换使用
    pickle
    模块创建一个字节流。)

    本节的Python编程部分更适合stackoverflow.com。但是,也有一个面向Unix的组件

    每个进程都有三个著名的文件描述符。虽然它们的名称分别为stdin、stdout和stderr,但实际上它们的文件号是已知的,分别为0、1和2。要运行程序并捕获其stdout和file-number-1输出,必须将该进程的file-descriptor-1连接到文件或管道

    在命令行shell中,有以下语法:

    prog > file
    
    在一个进程中运行程序
    prog
    ,该进程的stdout连接到已移动到descriptor-slot-1的打开文件描述符。实际上,在系统调用级别执行所有操作是复杂的:

  • 打开文件。这将导致一个打开的文件描述符,其数量可能大于2,因为从0到2是您自己的stdin、stdout和stderr
  • 使用
    fork
    系统调用或其变体之一:这将克隆您自己
  • 在克隆中(但不是在原始中),将文件描述符从现在的位置移动到文件描述符1。然后关闭原始的编号较高的描述符(以及您已打开但不希望传递的任何其他描述符)
  • 使用
    exec
    调用系列中的一个调用