从shell管道中读取行,传递给exec,并保持为变量



我试图通过python脚本传递管道中的数据,并将此数据写入单独的变量以进行进一步处理

该脚本的主要目的是作为管道之间的层,记录解析错误和导致错误的原因。

应用程序:

echo '{"user": "Basic dGVzdDp0ZXN0"}' | script.py | rotatelogs {....}

我做了一个脚本:

cmd = ["/usr/bin/jq -c '.user |= if test("^[Bb]asic ") then .[6:] | @base64d | gsub (":.*$"; "")  else . end '"]
with open('/dev/stdin') as f: 
try:
subprocess.run(cmd, check = True, shell=True)
except subprocess.CalledProcessError:
with open('/path/to/parseerror.log', 'w') as pfile:
pfile.write(f.read())        

subprocess.run中的命令成功执行并产生其输出,但f.read()变为空如果我将变量f.read()的读取移动到执行subprocess.run,那么我将获得变量的值,但是命令subprocess.run将不会被执行(获取空管道输入)。

with open('/dev/stdin') as f: 
line=(f.read())
try:
subprocess.run(cmd, check = True, shell=True)
except subprocess.CalledProcessError:
....

如何将命令的执行与来自管道的参数结合起来,并记录传入管道本身?主要目标是通过脚本传递命令执行,并将接收到的管道参数写入单独的文件

您的方法读取直到EOF,这就是read()所做的,没有为子进程读取留下任何输入。试试readline()吧。

打开第二个stdin看起来也很奇怪。我猜你想要像

这样的东西
import sys
...
print(sys.stdin.readline(), end='')
subprocess.run(cmd, stdin=sys.stdin, shell=True, check=True)

实际上,如果你只有一个命令想要运行,你可以去掉shell=True

import shlex
...
subprocess.run(shlex.split(cmd), stdin=sys.stdin, check=True)

严格来说,stdin=sys.stdin并不重要(子进程将继承其父进程的标准输入,并根据自己的喜好使用或多或少),但它记录了您的意图。

奇怪的是,即使只有一个readline(),我也会得到你描述的相同症状。我可以使用显式的read():

来解决它。
subprocess.run(shlex.split(cmd), input=sys.stdin.read(), text=True, check=True)

…但是,如果你需要处理潜在的大量输入,这显然是没有吸引力的。

相反的情况不起作用;在一般情况下,该命令可以读取所有可用的输入,直到EOF(尽管有些命令,如head,不能),然后在子进程完成后,Python脚本将没有任何东西可以读取。

你让这件事变得更困难了。为了从管道(如echo "some data with spaces" | script.py)中读取,您可以使用任何标准输入法从stdin中读取。

同样,要将数据传递给另一个进程,只需使用任何标准输出方法写入stdout即可。操作系统将为您处理重定向。 例如:

# script.py
for line in input():
print(line)

现在

echo "my first linenmy second line" | python script.py

你会得到这样的输出:

my first line
my second line

相关内容

  • 没有找到相关文章

最新更新