from subprocess import Popen,PIPE
1.光标处于闪烁等待状态,不能实时输出测试cmd界面.
[原因]:使用communicate()函数,需要等脚本执行完才返回。
def communicate(self, input=None):
"""Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate.
The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child.
communicate() returns a tuple (stdout, stderr).
"""
[方案]:用subprocess.poll()函数替代, 程序运行完毕后返回1. 否则为None/0.
def poll(self):
"""Check if child process has terminated. Set and return returncode attribute."""
return self._internal_poll()
2. 输出结果没有换行,一大坨...
[原因]: 未使用
[方案]: 使用while 循环结合readline + poll() 函数, 出来一行打印一行.... stdout.readline()
Fail 代码:
1 p1 = Popen(['bash.exe', 'run_all_tests.sh', 'win32'], stdout=PIPE, shell=True) 2 print repr(p1.communicate()[0]) #communicate 函数
PASS 代码:
#
1 p1 = Popen(['bash.exe', 'run_all_tests.sh', 'win32'], stdout=subprocess.PIPE, shell=True) 2 while p1.poll() is None: 3 data = p1.stdout.readline() 4 print data 5 #print repr(p1.communicate()[0])
''' # 下面多了层循环,为一个个字符打印 xxx 3 while p1.poll() is None: 4 for line in p1.stdout.readline(): 5 print line 6 '''
3.传递系统变量env path 的两种方式.
3.1 模仿命令行,windows 用 set 去设置
3.2 [推荐] 不适用set 命令行,直接传递my_env 参数到subpross.Popen()类初始化. 这样可以有效避免字符串转义符号的问题
查看Popen 类帮助文档如下
1 class Popen(object): 2 """ Execute a child program in a new process. 3 4 For a complete description of the arguments see the Python documentation. 5 6 Arguments: 7 args: A string, or a sequence of program arguments. 8 9 bufsize: supplied as the buffering argument to the open() function when 10 creating the stdin/stdout/stderr pipe file objects 11 12 executable: A replacement program to execute. 13 14 stdin, stdout and stderr: These specify the executed programs' standard 15 input, standard output and standard error file handles, respectively. 16 17 preexec_fn: (POSIX only) An object to be called in the child process 18 just before the child is executed. 19 20 close_fds: Controls closing or inheriting of file descriptors. 21 22 shell: If true, the command will be executed through the shell. 23 24 cwd: Sets the current directory before the child is executed. 25 26 env: Defines the environment variables for the new process. 27 28 universal_newlines: If true, use universal line endings for file 29 objects stdin, stdout and stderr. 30 31 startupinfo and creationflags (Windows only) 32 33 Attributes: 34 stdin, stdout, stderr, pid, returncode 35 """ 36 _child_created = False # Set here since __del__ checks it 37 38 def __init__(self, args, bufsize=0, executable=None, 39 stdin=None, stdout=None, stderr=None, 40 preexec_fn=None, close_fds=False, shell=False, 41 cwd=None, env=None, universal_newlines=False, 42 startupinfo=None, creationflags=0): 43 """Create new Popen instance."""
所以代码加入参数即可:
1 p1 = Popen(['bash.exe', 'run_all_tests.sh', 'win32'], stdout=PIPE, shell=True, env=my_env)
4. subprocess.call(), Popen() 中shell=False 与shell=True的区别?
如下:但注意这种情况下,此cmd 执行完毕后就关闭.
所以最好用3.2 的方法设置env.
1 #默认shell= False时,Fail 2 subprocess.call(['set', 'CUDA_VISIBLE_DEVICES=%s ', % self.gpuid]) 3 4 #默认shell=True时,PASS 5 subprocess.call(['set', 'CUDA_VISIBLE_DEVICES=%s ', % self.gpuid],shell=True)
参考: https://blog.csdn.net/xiaoyaozizai017/article/details/72794469