在一个带有子进程的外壳中按顺序运行 shell 命令



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

这是我从终端运行的命令字符串,您可以看到它包含多个按顺序运行的命令,直到创建 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

如何实现终端般的执行?同样,顺序至关重要。

/

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

默认情况下,shell=True使用/bin/shsource外壳内置暗示了 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)

最新更新