尝试使用stdin时在Python中遇到错误:不支持操作:文件名

2024-10-03 06:29:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试在一个xml文件中std。我从subversion读取了xml文件,更新了文件中的一行,现在我尝试使用副总统大人和stdin

test = subprocess.Popen('svn cat http://localhost/svn/WernerTest/JenkinsJobTemplates/trunk/smartTemplate.xml --username admin --password admin', stdout=subprocess.PIPE, universal_newlines=True)
job = test.stdout.read().replace("@url@", "http://localhost/svn/WernerTest/TMS/branches/test1")
output = io.StringIO()
output.write(job)
subprocess.Popen('java -jar D:\\applications\\Jenkins\\war\\WEB-INF\\jenkins-cli.jar\\jenkins-cli.jar -s http://localhost:8080/ create-job test7', stdin=output)

我得到了以下错误:

^{pr2}$

那么如何将更新后的文件传递给下一个子进程呢?在


Tags: 文件testlocalhosthttpoutputadminstdinstdout
2条回答

使用管道并将数据直接写入该管道:

test = subprocess.Popen(
    'svn cat http://localhost/svn/WernerTest/JenkinsJobTemplates/trunk/smartTemplate.xml  username admin  password admin',
    stdout=subprocess.PIPE, universal_newlines=True)
job = test.stdout.read().replace("@url@", "http://localhost/svn/WernerTest/TMS/branches/test1")

jenkins = subprocess.Popen(
    'java -jar D:\\applications\\Jenkins\\war\\WEB-INF\\jenkins-cli.jar\\jenkins-cli.jar -s http://localhost:8080/ create-job test7',
    stdin=subprocess.PIPE, universal_newlines=True)
jenkins.communicate(job)

^{} method接受第一个参数并将其作为stdin发送到子进程。在

注意,我也为Jenkins设置了^{} argumentTrue;另一种方法是将job字符串显式编码为Jenkins可以接受的合适的编解码器。在

Popen()只接受真实的文件(至少是有效的.fileno())。 @Martijn Pieters♦' answer显示了如果您可以一次将所有数据加载到内存中,如何传递数据(另外,jenkins进程直到svn产生all输出才会启动)。在

下面是如何一次读取一行(svn和jenkins进程并行运行):

#!/usr/bine/env python3
from subprocess import Popen, PIPE

with Popen(svn_cmd, stdout=PIPE, bufsize=1, universal_newlines=True) as svn, \
     Popen(java_cmd, stdin=PIPE, bufsize=1, universal_newlines=True) as java:
    for line in svn.stdout:
        line = line.replace('@url@', 'http://localhost/svn/WernerTest/TMS/branches/test1')
        java.stdin.write(line)
if java.returncode != 0:
   "handle error"

请参见下面的svn_cmdjava_cmd定义(在Windows上不需要shlex.split(cmd)注意:不shell=True)。在


如果您不需要替换@url@,那么它看起来就像您正在尝试模拟:svn_cmd | java_cmd管道,其中:

^{2}$

最简单的方法就是把贝壳搅得七零八落:

#!/usr/bin/env python
import subprocess

subprocess.check_call(svn_cmd + ' | ' + java_cmd, shell=True)

您可以在Python中模拟它:

#!/usr/bin/env python3
from subprocess import Popen, PIPE

#NOTE: use a list for compatibility with POSIX systems
with Popen(java_cmd.split(), stdin=PIPE) as java, \
     Popen(svn_cmd.split(), stdout=java.stdin):
    java.stdin.close() # close unused pipe in the parent
    # no more code here (the for-loop is inside an OS code that implements pipes)
if java.returncode != 0:
   "handle error here"

How do I use subprocess.Popen to connect multiple processes by pipes?

相关问题 更多 >