最近忙于实习好久都没写博客啦,昨天由于对于bash和subprocess模块的不熟悉,浪费了一天的时间(留下了没有技术的泪水TOT)。
我一开始想实现的是用subprocess.Popen()打开两个子进程,可是直接Popen(cmd)会报No Such File错误,就是找不到这个命令。我已经想到了因为Popen()没有继承我的环境变量,所以导致了这个错误。说来话长不想说了,直接说重点吧。就是怎么让Popen继承你的环境变量呢?如下:
subprocess.Popen(['/bin/bash', '-i', '-c','CMD'])
CMD就是你要执行的命令。这里的-i就是初始化的意思,以/home/你的名字/.bashrc来初始化,所以用户的环境变量就会被加入Popen所创建的这个subprocess。
到了这里,我以为我能轻松的解决我在一个代码中创建两个子进程的问题,结果是我太年轻了。
我创建子进程时希望等待它执行完成后返回。声明:sp=subprocess。
子进程执行完成会返回sp.returncode,成功执行返回的是0。
官方推荐用sp.communicate()去阻塞等待子进程的执行结束。就是这个sp.communicat()我要疯了,第二个sp.communicate()永远都不返回!我上网查都是说什么管道满了所以阻塞,然后就试了N种方法发现我这个根本不是管道的问题。因为我根本没用sp.PIPE。
好了说多了都是泪。直接说怎么解决吧
错误的代码:
sp1 = subprocess.Popen(['/bin/bash', '-i', '-c','CMD1'])
sp1.communicate()
sp2 = subprocess.Popen(['/bin/bash', '-i', '-c','CMD2'])
sp2.communicate()
正确的代码:
sp1 = subprocess.Popen(['/bin/bash', '-i', '-c','CMD1'])
sp1.communicate()
sp2 = subprocess.Popen(['/bin/bash', '-i', '-c','CMD2'],start_new_session=True)
sp2.communicate()
总结:
好好看官方的文档。
Bounus:
想要实时查看子进程的输出可以这样:
sp = subprocess.Popen(cmd, stderr=sys.stderr,stdout=sys.stdout, start_new_session=True)
不用谢我。