Som*_*ter 5 python windows subprocess call popen
我在 SO 上浏览了一篇又一篇文章,寻找一种使用 subprocess.popen 在参数内使用引号的方法,但我似乎找不到方法。
这在命令行下工作得很好
runme.bat --include="check|check2"
Run Code Online (Sandbox Code Playgroud)
Python
#!/usr/bin/python
import sys
import subprocess
import shlex
#command_line = "./runme.sh --include=\"check|check2\""
command_line = "runme.bat --include=\"check|check2\""
arg = shlex.shlex(command_line)
arg.quotes = '"'
arg.whitespace_split = True
arg.commenters = ''
command_line_args = list(arg)
print command_line_args
command_line_process = subprocess.Popen(
command_line_args,
universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
line = ""
while True:
line = command_line_process.stdout.readline()
if line:
print line
break
Run Code Online (Sandbox Code Playgroud)
运行文件
echo %* >> someargs.txt
Run Code Online (Sandbox Code Playgroud)
runme.sh
#!/bin/bash
echo $@
Run Code Online (Sandbox Code Playgroud)
我听说 subprocess.call() 是解决这个问题的方法,但我希望能够在程序运行时逐行迭代子进程的输出。
编辑:
这似乎是Python中的一个错误,因为在cmd中运行runme.bat可以正常工作,在linux中运行runme.py可以正常工作,只有在Windows上运行runme.py时才能正常工作。我在这里创建了一张票。
编辑2:
这显然不是一个 python bug 哈哈。查看所选答案。
在 Windows 上,字符串是本机 API。为了避免不必要的转换,请将命令作为字符串传递:
#!/usr/bin/env python
from __future__ import print_function
import subprocess
command = 'runme.bat --include="check|check2"'
process = subprocess.Popen(command,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
universal_newlines=True, bufsize=1)
for line in iter(process.stdout.readline, ''):
print(line, end='')
Run Code Online (Sandbox Code Playgroud)
stderr=subprocess.STDOUT将 stderr 合并到 stdout。如果您设置了stderr=PIPE,那么您应该与读取process.stderr并行,process.stdout否则您的程序可能会死锁。
Popen()将字符串传递给CreateProcess()Windows 函数。如果子进程实际上是一个批处理文件;您可能应该shell=True显式传递以明确该命令是使用cmd.exe规则解释的(^、|等是元字符,有关更多详细信息,请阅读此答案中的链接)。
%1如果您想使用而不是传递参数,%*以便它包含
整个--include="check|check2"(不仅仅是--include),那么您可以在参数周围使用额外的引号,如@eryksun 在评论中建议的那样:
command = '"runme.bat" "--include="check^^^|check2""'
Run Code Online (Sandbox Code Playgroud)
注意:三重^逃离|这里。
| 归档时间: |
|
| 查看次数: |
8796 次 |
| 最近记录: |