[英]Saving shell command output in python script to text file
我设法在我的 python 脚本中调用和使用终端命令,它在其中工作。
但目前我正在尝试将此命令的“输出”结果保存到文本文件中,但出现错误。
这是我正确执行的初始代码:
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 operation on closed file
当我在网上找到这个文件时,我确实关闭了该文件。 那么我错在哪里?
这其中的 Python 编程部分更适合 stackoverflow.com。 但是,也有一个面向 Unix 的组件。
每个进程都有三个众所周知的文件描述符。 虽然它们有名称——stdin、stdout 和 stderr——但它们实际上是通过它们的文件编号来识别的,它们分别是 0、1 和 2。 要运行一个程序并捕获它的标准输出(它的 file-number-1 输出),您必须将该进程的file-descriptor-1 连接到一个文件或管道。
在命令行 shell 中,有这样的语法:
prog > file
运行程序prog
,在其标准输出连接到已移动到描述符插槽 1 的打开文件描述符的进程中。 实际上,在系统调用级别实现所有这些是很复杂的:
fork
系统调用或其变体之一:这会克隆您自己。exec
系列调用之一来终止您自己(克隆),但在此过程中,将所有内容替换为程序prog
。 这将维护所有打开的文件描述符,包括指向您在步骤 3 中移动的文件或管道的描述符。一旦exec
成功,您将不再存在并且无法执行任何操作。 (如果exec
失败,报告失败并退出。) Python 就是这样,这个多步骤序列在subprocess
模块中已经为您完成了,并带有花哨的错误检查。 您可以使用os.system
而不是使用subprocess.Popen
。 它被设计为使用管道——实际上比文件更难——所以如果你真的想重定向到一个文件,而不是简单地通过管道读取程序的输出,你需要先打开文件,然后调用subprocess.Popen
。
在任何情况下,更改 Python 进程的sys.stdout
都没有帮助,因为sys.stdout
是一个完全独立于底层文件描述符系统的 Python 数据结构。 通过open
Python 流,您确实获得了文件描述符(以及 Python 数据结构),但它不是 file-descriptor-number-1。 底层文件描述符编号,无论它是什么,都必须在克隆中的fork
调用之后移动到 slot-1 位置。 即使您使用subprocess.Popen
,Python 将移动的唯一描述符(post-fork)是您作为stdout=
参数传递的描述符。
(Subprocess 的Popen
接受以下任何一种:
stream.fileno()
来获取描述符编号,或者stdin=
、 stdout=
还是stderr=
的参数,或者subprocess.PIPE
或者,对于stderr=
, subprocess.STDOUT
:这些告诉它 Python 应该创建一个管道,或者为特殊的stderr=subprocess.STDOUT
重新使用先前创建的 stdout 管道。 该库非常漂亮,并且知道如何使用 Python exec
、执行失败或子进程中发生的各种其他故障来报告。 它使用另一个带有 close-on-exec 的辅助管道来执行此操作。 此管道上的 EOF 表示执行成功; 否则到达这个额外管道的数据包括失败,使用pickle
模块转换为字节流。)
出于某种原因,我无法发布我的问题,所以我想我在这里发表评论。 我需要一些关于在 python 中输出文本的帮助。
我使用 kaldi ASR 训练了一个语言模型,现在我正在尝试将它链接到 vosk API 以制作语音到文本软件。 后端引擎是 kaldi,前端工作涉及 python。 python脚本如下:
from vosk import Model, KaldiRecognizer, SetLogLevel
import os
import wave
import json
fname = input ( "Enter audio file name: " )
wav = ".wav"
txt = ".txt"
transcript = fname + txt
audiofilename = fname + wav
#wav = input( "enter audio filename with extension: " )
wf = wave.open(audiofilename, "rb")
model = Model(".")
rec = KaldiRecognizer(model, wf.getframerate())
results = []
# recognize speech using vosk model
while True:
data = wf.readframes(4000)
if len(data) == 0:
break
if rec.AcceptWaveform(data):
part_result = json.loads(rec.Result())
results.append(part_result)
print(rec.Result())
else:
print(rec.PartialResult())
part_result = json.loads(rec.FinalResult())
results.append(part_result)
# forming a final string from the words
text = ''
for r in results:
text += r['text'] + ' '
print(f"Vosk thinks you said:\n {text}")
#print(rec.FinalResult())
# convert list of JSON dictionaries to list of 'Word' objects
list_of_Words = []
for sentence in results:
if len(sentence) == 1:
# sometimes there are bugs in recognition
# and it returns an empty dictionary
# {'text': ''}
continue
for obj in sentence['result']:
w = custom_Word.Word(obj) # create custom Word object
list_of_Words.append(w) # and add it to list
wf.close() # close audiofile
# output to the screen
for word in list_of_words:
print(word.to_string())```
The output is working correctly. Info displayed on Shell is fine.
I cant figure out how to use f.write or similar command to save the shell output (all of it or any particular output I need from the code) and save it to a text file.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.