我试图通过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