【发布时间】:2020-10-05 04:27:47
【问题描述】:
我无法找到使用 linux sort 命令作为我的 python 脚本输入的解决方案。
例如我想遍历sort -mk1 <(cat file1.txt) <(cat file2.txt))的结果
通常我会使用Popen 并使用next 和stdout.readline() 遍历它,类似于:
import os
import subprocess
class Reader():
def __init__(self):
self.proc = subprocess.Popen(['sort -mk1', '<(', 'cat file1.txt', ')', '<(', 'cat file2.txt', ')'], stdout=subprocess.PIPE)
def __iter__(self):
return self
def __next__(self):
while True:
line = self.proc.stdout.readline()
if not line:
raise StopIteration
return line
p = Reader()
for line in p:
# only print certain lines based on some filter
使用上面的,我会得到一个错误:No such file or directory: 'sort -mk1'
经过一番研究,我想我不能使用 Popen,必须使用os.execl 才能使用bin/bash
所以现在我尝试如下:
import os
import subprocess
class Reader():
def __init__(self):
self.proc = os.execl('/bin/bash', '/bin/bash', '-c', 'set -o pipefail; sort -mk1 <(cat file1.txt) <(cat file2.txt)')
def __iter__(self):
return self
def __next__(self):
while True:
line = self.proc.stdout.readline()
if not line:
raise StopIteration
return line
p = Reader()
for line in p:
# only print certain lines based on some filter
问题在于它实际上会立即打印所有行。我想一种解决方案是将其结果通过管道传输到一个文件中,然后在 python 中我遍历该文件。但我真的不想将它保存到文件然后过滤它,似乎没有必要。是的,我可以使用其他 linux 命令,例如 awk,但我想使用 python 进行进一步处理。
所以问题是:
- 有没有办法让
Popen的解决方案起作用? - 如何使用第二种解决方案遍历
sort的输出?
【问题讨论】:
-
Process Subtituion (
<( command )) 是 bash 提供的东西(运行命令,创建一个 FIFO 并将其替换为 FIFO 的名称)。如果您将这些作为参数提供给sort,它将无法执行您想要的操作(很可能sort会将<(和)视为文件名)。为什么你不能简单地做sort -mk filename1.txt filename2.txt? -
对于您的第二种情况,使用
os.exec*将替换整个过程,因此它不会继续您的 python 脚本中的下一条语句,因此处理输出没有意义。还没有尝试过,但为什么不能像第二个示例一样使用Popen来生成运行bash的进程? -
我想我不确定如何使用 Popen 来生成运行中的 bash
标签: python linux subprocess