Khi @mark làm rõ đó là hệ thống Linux, tập lệnh có thể dễ dàng tự hoàn toàn độc lập, tức là, daemon, bằng cách làm theo recipe này. (Bạn cũng có thể làm điều đó trong phụ huynh sau os.fork
và chỉ sau đó os.exec...
quy trình con).
Chỉnh sửa: để làm rõ một số chi tiết nhận xét của wrt @ mark về câu trả lời của tôi: các đặc quyền siêu người dùng không cần thiết để "daemonize" quy trình theo công thức nấu ăn, cũng không cần thay đổi thư mục làm việc hiện tại mã trong công thức làm điều đó và hơn thế nữa, đó không phải là phần quan trọng - đúng hơn là chuỗi logic hợp lý của các cuộc gọi fork
, _exit
và setsid
). Các biến thể os.exec...
khác nhau làm không kết thúc bằng e
sử dụng môi trường của quy trình gốc, do đó phần cũng dễ dàng - xem Python online docs.
Để giải quyết các đề xuất được đưa ra trong nhận xét và câu trả lời của người khác: Tôi tin rằng subprocess
và multiprocessing
mỗi lần không làm daemon quá trình con, có vẻ như những gì @mark cần; kịch bản có thể tự thực hiện, nhưng vì một số mã phải hoạt động fork
s và setsid
, có vẻ như tôi giữ cho tất cả sinh sản trên mặt phẳng cấp thấp hơn là trộn một số cấp cao và một số thấp mã cấp trong quá trình hoạt động. Dưới đây là một phiên bản rút gọn và đơn giản hóa của công thức tại URL trên, được thiết kế để được gọi trong cha mẹ để sinh ra một daemon - theo cách này, mã có thể được sử dụng để thực thi các thực thi không phải Python cũng như vậy. . Như đã nêu, mã phải đáp ứng nhu cầu @mark giải thích, tất nhiên nó có thể được điều chỉnh theo nhiều cách - tôi khuyên bạn nên đọc công thức gốc và các bình luận và thảo luận của nó, cũng như những cuốn sách mà nó đề xuất, để biết thêm thông tin.
import os
import sys
def spawnDaemon(path_to_executable, *args)
"""Spawn a completely detached subprocess (i.e., a daemon).
E.g. for mark:
spawnDaemon("../bin/producenotify.py", "producenotify.py", "xx")
"""
# fork the first time (to make a non-session-leader child process)
try:
pid = os.fork()
except OSError, e:
raise RuntimeError("1st fork failed: %s [%d]" % (e.strerror, e.errno))
if pid != 0:
# parent (calling) process is all done
return
# detach from controlling terminal (to make child a session-leader)
os.setsid()
try:
pid = os.fork()
except OSError, e:
raise RuntimeError("2nd fork failed: %s [%d]" % (e.strerror, e.errno))
raise Exception, "%s [%d]" % (e.strerror, e.errno)
if pid != 0:
# child process is all done
os._exit(0)
# grandchild process now non-session-leader, detached from parent
# grandchild process must now close all open files
try:
maxfd = os.sysconf("SC_OPEN_MAX")
except (AttributeError, ValueError):
maxfd = 1024
for fd in range(maxfd):
try:
os.close(fd)
except OSError: # ERROR, fd wasn't open to begin with (ignored)
pass
# redirect stdin, stdout and stderr to /dev/null
os.open(os.devnull, os.O_RDWR) # standard input (0)
os.dup2(0, 1)
os.dup2(0, 2)
# and finally let's execute the executable for the daemon!
try:
os.execv(path_to_executable, args)
except Exception, e:
# oops, we're cut off from the world, let's just give up
os._exit(255)
Tại sao bạn không sử dụng tiến trình con. Mở để thực hiện việc này? –
S. Lott: tôi sẽ có thể giết/khởi động lại quá trình ứng dụng web/cha mẹ sau khi thực hiện subprocess.Popen? cảm ơn – mark