【问题标题】:executing shell script using subprocess.Popen in Python?在 Python 中使用 subprocess.Popen 执行 shell 脚本?
【发布时间】:2014-01-15 14:47:54
【问题描述】:

我正在尝试从 Python 程序执行 shell 脚本。我没有使用subprocess.call,而是使用subprocess.Popen,因为我想在变量中执行shell脚本时查看shell脚本的输出和错误。

#!/usr/bin/python

import subprocess
import json
import socket
import os

jsonStr = '{"script":"#!/bin/bash\\necho Hello world\\n"}'
j = json.loads(jsonStr)

shell_script = j['script']

print shell_script

print "start"
proc = subprocess.Popen(shell_script, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
if stderr:
   print "Shell script gave some error"
   print stderr
else:
   print stdout
   print "end" # Shell script ran fine.

但是每当我运行上面的代码时,我总是会遇到这样的错误 -

Traceback (most recent call last):
  File "hello.py", line 29, in <module>
    proc = subprocess.Popen(shell_script, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

知道我在这里做错了什么吗?

【问题讨论】:

    标签: python json bash shell


    【解决方案1】:

    要执行以字符串形式给出的任意 shell 脚本,只需添加 shell=True 参数即可。

    #!/usr/bin/env python
    from subprocess import call
    from textwrap import dedent
    
    call(dedent("""\
        #!/bin/bash
        echo Hello world
        """), shell=True)
    

    【讨论】:

      【解决方案2】:

      您可以使用 shell=True 执行它(您也可以省略 shebang)。

      proc = subprocess.Popen(j['script'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = proc.communicate()

      或者,你可以这样做:

      proc = subprocess.Popen(['echo', 'Hello world'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

      或者,您可以将脚本写入文件,然后调用它:

      inf = open('test.sh', 'wb')
      inf.write(j['script'])
      inf.close()
      
      print "start"
      proc = subprocess.Popen(['sh', 'test.sh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      (stdout, stderr) = proc.communicate()
      

      【讨论】:

        最近更新 更多