使用子进程在一个shell中以顺序方式运行shell命令

时间:2016-05-25 19:26:30

标签: python-2.7 subprocess

我在使用子进程类运行一系列顺序命令时遇到困难,我需要这样做,这样一个python程序可以调用cv virtualenv的安装,然后运行另一个python程序(需要在其中运行)的virtualenv)

这是我从终端运行的命令strign,你可以看到它包含多个按顺序运行的命令,直到创建cv虚拟环境:

sudo pip install virtualenv virtualenvwrapper && sudo rm -rf ~/.cache/pip && export WORKON_HOME=$HOME/.virtualenvs && source /usr/local/bin/virtualenvwrapper.sh && source ~/.bashrc && mkvirtualenv cv

在终端中运行它会返回如下内容:

(cv) name@computer:~$ 
从那里我可以运行我需要openCV的python脚本

到目前为止,我的代码是:

from subprocess import Popen, PIPE, STDOUT

cmd1 = 'sudo pip install virtualenv virtualenvwrapper'
cmd2 = 'sudo rm -rf ~/.cache/pip'
cmd3 = 'export WORKON_HOME=$HOME/.virtualenvs'
cmd4 = 'source /usr/local/bin/virtualenvwrapper.sh'
cmd5 = 'source ~/.bashrc'
cmd6 = 'mkvirtualenv cv'
cmd7 = 'cd /script path'
cmd8 = 'python novo.py'


final = Popen("{}; {}; {}; {}; {}; {}; {}; {}".format(cmd1, cmd2,cmd3,    cmd4, cmd5, cmd6, cmd7, cmd8), shell=True, stdin=PIPE, 
      stdout=PIPE, stderr=STDOUT, close_fds=True)

stdout, nothing = final.communicate()
log = open('log', 'w')
log.write(stdout)
log.close()

日志中的错误如下所示:

/bin/sh: 1: source: not found
/bin/sh: 1: source: not found
/bin/sh: 1: mkvirtualenv: not found

我如何实现像执行一样的终端? 再次,顺序是至关重要的。

1 个答案:

答案 0 :(得分:0)

  

/ bin / sh:1:来源:未找到

shell=True默认使用/bin/shsource shell内置提示bash。通过executable='/bin/bash'

不过,您可以使用多行字符串文字:

#!/usr/bin/env python3
import sys
from subprocess import check_call, DEVNULL, STDOUT

with open('log', 'wb', 0) as file:
   check_call("""set -e -x
{python} -mpip install --user virtualenv virtualenvwrapper
rm -rf ~/.cache/pip
export WORKON_HOME=$HOME/.virtualenvs
source /path/to/virtualenvwrapper.sh
source ~/.bashrc
mkvirtualenv cv
cd /script path
{python} novo.py
""".format(python=sys.executable),
              shell=True, executable='/bin/bash',
              stdin=DEVNULL, stdout=file, stderr=STDOUT, close_fds=True)

或者将命令保存到单独的bash脚本中并改为运行脚本。

DEVNULL是Python 3的特性 - 在Python 2上也很容易模仿它:DEVNULL = open(os.devnull, 'r+b', 0)