这里的主要目标是创建一个守护进程 - 产生函数。守护进程需要运行任意程序(即使用subprocess
)。
到目前为止,我在daemonizer.py
模块中的内容是:
import os
from multiprocessing import Process
from time import sleep
from subprocess import call, STDOUT
def _daemon_process(path_to_exec, std_out_path, args, shell):
with open(std_out_path, 'w') as fh:
args = (str(a) for a in args)
if shell:
fh.write("*** LAUNCHING IN SHELL: {0} ***\n\n".format(" ".join([path_to_exec] + list(args))))
retcode = call(" ".join([path_to_exec] + list(args)), stderr=STDOUT, stdout=fh, shell=True)
else:
fh.write("*** LAUNCHING WITHOUT SHELL: {0} ***\n\n".format([path_to_exec] + list(args)))
retcode = call([path_to_exec] + list(args), stderr=STDOUT, stdout=fh, shell=False)
if retcode:
fh.write("\n*** DAEMON EXITED WITH CODE {0} ***\n".format(retcode))
else:
fh.write("\n*** DAEMON DONE ***\n")
def daemon(path_to_executable, std_out=os.devnull, daemon_args=tuple(), shell=True):
d = Process(name='daemon', target=_daemon_process, args=(path_to_executable, std_out, daemon_args, shell))
d.daemon = True
d.start()
sleep(1)
尝试在bash中运行时(这会在当前目录中创建一个名为test.log
的文件。):
python -c"import daemonizer;daemonizer.daemon('ping', std_out='test.log', daemon_args=('-c', '5', '192.168.1.1'), shell=True)"
它正确生成一个启动ping
的守护进程,但它不尊重传递的参数。如果shell也设置为False
,则为true。日志文件明确指出它试图通过传递的参数启动它。
作为创建以下可执行文件的概念证明:
echo "ping -c 5 192.168.1.1" > ping_test
chmod +x ping_test
以下按预期方式工作:
python -c"import daemonizer;daemonizer.daemon('./ping_test', std_out='test.log', shell=True)"
如果我在call
- 目标之外测试相同的multiprocessing.Process
代码,它会按预期工作。
那么如何修复这个混乱以便我可以使用参数生成进程?
我对完全不同的结构和模块持开放态度,但它们应该包含在标准的结构和模块中,并与python 2.7.x兼容。要求是daemon
函数应该在脚本中异步调用几次并且每个都生成一个守护进程,并且它们的目标进程应该能够在不同的CPU上结束。此外,脚本需要能够在不影响生成的守护进程的情况下结束。
作为奖励,我注意到我需要有一个sleep
产卵才能在脚本终止太快的情况下工作。有什么方法可以解决这个任意黑客攻击和/或我需要多长时间让它等待安全?
答案 0 :(得分:2)
你的论点正在被用完"通过印刷它们!
首先,你这样做:
args = (str(a) for a in args)
创建一个生成器,而不是列表或元组。所以当你以后这样做时:
list(args)
消耗这些论点,他们不会第二次看到它们。所以你再次这样做:
list(args)
获得一个空列表!
您可以通过注释掉您的打印报表来解决此问题,但更好的方法是首先创建一个列表:
args = [str(a) for a in args]
然后您可以直接使用args
而不是list(args)
。而且它总会有内在的论点。