簡體   English   中英

如何使用python子進程模塊執行包含腳本的字符串

[英]How to execute a string containing a script using python subprocess module

我收到一個字符串腳本,並試圖找到一種使用python的子進程模塊執行該腳本的方法。 例如

import subprocess
script = """#!/usr/bin/python
            print "inside script"
         """
subprocess.Popen(script)

這引發OSError:說沒有這樣的文件或目錄,這很公平,因為我認為它試圖查找命令名。

然后subprocess.Popen(script, shell=True)我嘗試了subprocess.Popen(script, shell=True) ,它僅適用於shell命令,完全忽略了#! 在腳本的頂部。 有什么辦法可以讓suprocess運行以字符串形式存儲的腳本(例如其可執行​​文件)?

正如你在讀POPEN Python文檔的參數Popen是一個可執行文件來啟動,而不是一些腳本的內容來執行。 您不能以這種方式使用Popen

如果確實需要,可以將腳本寫入文件,然后將該文件名傳遞給Popen,但這對於您遇到的任何問題似乎都不是一個很好的解決方案。

看起來您只需要從字符串中執行一些Python代碼,就可以使用exec內置函數

此解決方案基於-c (編譯)Python解釋器cmdline參數。 它完全忽略了使用shell屬性。

Popen可以以類似方式創建。 subprocess.call用於顯示腳本實際上已執行,並且python解釋器的返回代碼已由執行的代碼更改。

import subprocess

executable_code = """
print 'inside script'
print 123
"""

code_with_exception = """
raise Exception()
"""

ok_rc = subprocess.call(['python', '-c', executable_code])
assert ok_rc == 0

bad_rc = subprocess.call(['python', '-c', code_with_exception])
assert bad_rc == 1

進一步的改進是跳過“ python”硬編碼字符串並使用sys.executable

一個字符串,給出有意義的系統上Python解釋器的可執行二進制文件的絕對路徑。 如果Python無法檢索其可執行文件的真實路徑,則sys.executable將為空字符串或無。

import sys
import subprocesss
code = "raise Exception()"
bad_rc = subprocess.call([sys.executable, '-c', code])
assert bad_rc == 1

您可以通過將腳本泵入子python的stdin來運行腳本。 對於較大的腳本,這可能是首選的解決方案:

import sys
import subprocess as subp
import shutil

script = """\
import sys
print "hello", sys.argv
"""

p = subp.Popen([sys.executable, '-', 'arg1', 'arg2'], stdin=subp.PIPE)
p.stdin.write(script)
p.stdin.close()
p.wait()

我在ssh連接中使用此技巧來控制遠程服務器。

要使用subprocess模塊將字符串作為Python腳本執行:

>>> import subprocess, sys, textwrap
>>> subprocess.call(textwrap.dedent('''
...    print "Hello, world!"
... '''), shell=True, executable=sys.executable)
Hello, world!
0

盡管正如@wich所建議的那樣,您可以使用Python內置函數exec() -這是關於Python 2的聲明:

>>> exec 'print "Hello, exec!"'
Hello, exec!

如果要在其他過程中運行Python代碼,則可以使用multiprocessingconcurrent.futures模塊

#!/urs/bin/env python2
from multiprocessing import Process, freeze_support

def run(code):
    exec code # Python 2

if __name__ == "__main__":
    freeze_support()
    Process(target=run, args=['print "Hello, multiprocessing"']).start()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM