尝试使用标准输入时在 Python 中出现错误:io.UnsupportedOperation: fileno
Getting an error in Python when trying to use stdin: io.UnsupportedOperation: fileno
我正在尝试在 xml 文件中进行 std。我从颠覆中读取了 xml 文件,更新了文件中的一行,现在我正在尝试使用 subporcess.Popen 和 stdin
创建一个 jenkins 作业
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)
我收到以下错误:
Traceback (most recent call last): File "D:\scripts\jenkinsGetJobs.py", line 20, in <module>
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)
File "D:\applications\Python 3.5\lib\subprocess.py", line 914,
in __init__errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "D:\applications\Python 3.5\lib\subprocess.py", line 1127, in _get_handles
p2cread = msvcrt.get_osfhandle(stdin.fileno())
io.UnsupportedOperation: fileno
那么如何将更新后的文件传递给下一个子进程呢?
使用管道并将数据直接写入该管道:
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)
Popen.communicate()
method 获取第一个参数并将其作为标准输入发送到子进程。
请注意,我也将 Jenkins 的 universal_newlines
argument 设置为 True
;另一种方法是将 job
字符串显式编码为 Jenkins 将接受的合适的编解码器。
Popen()
只接受真实文件(至少 .fileno()
有效)。
显示了如果可以一次将数据全部加载到内存中如何传递数据(另外,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_cmd
、java_cmd
定义(在 Windows 上不需要 shlex.split(cmd)
-- 注意:不需要 shell=True
)。
如果您不需要替换 @url@
那么看起来您正在尝试模拟:svn_cmd | java_cmd
管道,其中:
svn_cmd = 'svn cat http://localhost/svn/WernerTest/JenkinsJobTemplates/trunk/smartTemplate.xml --username admin --password admin'
java_cmd = 'java -jar D:\applications\Jenkins\war\WEB-INF\jenkins-cli.jar\jenkins-cli.jar -s http://localhost:8080/ create-job test7'
最简单的方法是调用 shell:
#!/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?
我正在尝试在 xml 文件中进行 std。我从颠覆中读取了 xml 文件,更新了文件中的一行,现在我正在尝试使用 subporcess.Popen 和 stdin
创建一个 jenkins 作业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)
我收到以下错误:
Traceback (most recent call last): File "D:\scripts\jenkinsGetJobs.py", line 20, in <module>
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)
File "D:\applications\Python 3.5\lib\subprocess.py", line 914,
in __init__errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "D:\applications\Python 3.5\lib\subprocess.py", line 1127, in _get_handles
p2cread = msvcrt.get_osfhandle(stdin.fileno())
io.UnsupportedOperation: fileno
那么如何将更新后的文件传递给下一个子进程呢?
使用管道并将数据直接写入该管道:
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)
Popen.communicate()
method 获取第一个参数并将其作为标准输入发送到子进程。
请注意,我也将 Jenkins 的 universal_newlines
argument 设置为 True
;另一种方法是将 job
字符串显式编码为 Jenkins 将接受的合适的编解码器。
Popen()
只接受真实文件(至少 .fileno()
有效)。
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_cmd
、java_cmd
定义(在 Windows 上不需要 shlex.split(cmd)
-- 注意:不需要 shell=True
)。
如果您不需要替换 @url@
那么看起来您正在尝试模拟:svn_cmd | java_cmd
管道,其中:
svn_cmd = 'svn cat http://localhost/svn/WernerTest/JenkinsJobTemplates/trunk/smartTemplate.xml --username admin --password admin'
java_cmd = 'java -jar D:\applications\Jenkins\war\WEB-INF\jenkins-cli.jar\jenkins-cli.jar -s http://localhost:8080/ create-job test7'
最简单的方法是调用 shell:
#!/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?