[英]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代碼,則可以使用multiprocessing
或concurrent.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.