我有一些Python代码,偶尔需要跨越一个新进程,以“即发即忘”的方式运行shell脚本,即不阻塞。 shell 脚本不会与原始 Python 代码通信,实际上可能会终止调用 Python 进程,因此启动的 shell 脚本不能是调用 Python 进程的子进程。我需要将它作为一个独立的进程启动。
换句话说,假设我有 mycode.py 并启动 script.sh。然后 mycode.py 将继续处理而不会阻塞。脚本 script.sh 将独立执行一些操作,然后实际停止并重新启动 mycode.py。所以运行script.py的进程必须完全独立于mycode.py。我到底该怎么做呢?我认为 subprocess.Popen 不会阻塞,但仍然会创建一个子进程,一旦 mycode.py 停止,该子进程就会终止,这不是我想要的。
尝试在 script.sh 前面添加“nohup”。您可能需要决定如何处理 stdout 和 stderr;我只是将其放在示例中。
import os
from subprocess import Popen
devnull = open(os.devnull, 'wb') # Use this in Python < 3.3
# Python >= 3.3 has subprocess.DEVNULL
Popen(['nohup', 'script.sh'], stdout=devnull, stderr=devnull)
只需使用 subprocess.Popen 即可。以下内容在 Windows XP / Windows 7 和 Python 2.5.4、2.6.6 和 2.7.4 上运行正常。用 py2exe 转换后 - 未尝试过 3.3 - 它来自需要删除客户端计算机上过期的测试软件。
import os
import subprocess
import sys
from tempfile import gettempdir
def ExitAndDestroy(ProgPath):
""" Exit and destroy """
absp = os.path.abspath(ProgPath)
fn = os.path.join(gettempdir(), 'SelfDestruct.bat')
script_lines = [
'@rem Self Destruct Script',
'@echo ERROR - Attempting to run expired test only software',
'@pause',
'@del /F /Q %s' % (absp),
'@echo Deleted Offending File!',
'@del /F /Q %s\n' % (fn),
#'@exit\n',
]
bf = open(fn, 'wt')
bf.write('\n'.join(script_lines))
bf.flush()
bf.close()
p = subprocess.Popen([fn], shell=False)
sys.exit(-1)
if __name__ == "__main__":
ExitAndDestroy(sys.argv[0])
最简单的方法:
CMD = ['sleep', 'infinity']
os.spawnvpe(os.P_NOWAIT, CMD[0], CMD, os.environ)