簡體   English   中英

Python子進程—使用Ctrl-C關閉Django服務器和Docker容器,返回到終端

[英]Python subprocess — close Django server and Docker container with Ctrl-C, return to terminal

我試圖弄清楚如何正確關閉我的腳本,該腳本應該啟動在Docker容器(在Mac OS X上為boot2docker)上運行的Django服務器。 這是相關的代碼塊:

try:
    init_code = subprocess.check_output('./initdocker.sh', shell=True)
    subprocess.call('./startdockerdjango.sh', shell=True)
except subprocess.CalledProcessError:
    try:
        subprocess.call('./startdockerdjango.sh', shell=True)
    except KeyboardInterrupt:
        return

startdockerdjango.sh負責設置startdockerdjango.sh需要的環境變量並啟動服務器。 總體而言,腳本應該知道是進行首次設置和初始化,還是只是啟動容器和服務器。 捕獲CalledProcessError意味着第一次設置已經完成,並且容器和服務器可以剛剛啟動。 啟動工作正常,但是當用戶按Ctrl-C停止服務器時,服務器將正常停止,但是顯然啟動服務器的過程仍在進行。 如果按回車鍵,則可以返回到正常的終端命令提示符。 如果我執行諸如ls類的任何shell命令,那么它將執行該命令,然后我可以返回到終端。 我想更改代碼,以便如果用戶按Ctrl-C,則服務器和運行該服務器的容器將正常停止,然后再停止該過程並退出整個腳本。 如何才能做到這一點? 我不想在KeyboardInterrupt上終止或終止進程,因為那樣服務器和容器將無法正常停止,但會突然終止。

更新:我最近根據Padraic Cunningham的評論嘗試了以下方法:

try:
    init_code = subprocess.check_output('./initdocker.sh', shell=True)
    subprocess.call('./startdockerdjango.sh', shell=True)
except subprocess.CalledProcessError:
    try:
        startproc = subprocess.Popen('./startdockerdjango.sh')
    except KeyboardInterrupt:
        startproc.send_signal(SIGTERM)
        startproc.wait()
        return

這是我嘗試向服務器發送術語以正常關閉,然后使用wait()等待過程( startproc )完成。 但是,這導致容器和服務器突然終止,這是我試圖防止的事情。 如果我改用SIGINT,也會發生相同的情況。 第二種方法在做錯什么(如果有的話)? 我仍然想要和以前一樣的整體操作,即用一個Ctrl-C結束容器和服務器,然后退出腳本。

您可能要使用Popen創建過程。 它將使您對如何管理子進程有更多的控制權。

env = {"MY_ENV_VAR": "some value"}
proc = subprocess.Popen("./dockerdjango.sh", env=env)
try:
    proc.wait()
except KeyboardInterupt:
    proc.terminate() # on linux this gives the a chance to clean up,
    # or even ignore the signal entirely
    # use proc.send_signal(...) and the module signal to send other signals.
    # or proc.kill() if you wish to be kill the process immediately.

如果您在python中設置環境變量,則也會減少需要殺死的子進程。

最后,讓腳本知道執行首次初始化或服務器+容器啟動是不值得的。 相反,該腳本將僅嘗試首次安裝,然后在成功安裝后告訴用戶進行docker-compose up 對於我的特定情況,這比嘗試弄清楚如何讓Ctrl-C正確關閉服務器然后退出腳本更好。

要重置django服務器子進程,請在您的終端中執行:

$ sudo lsof -i tcp:8080
$ sudo lsof -i tcp:8080|awk '{print $2}'|cut -d/ -f 1|xargs kill

暫無
暫無

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

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