AberSheeran
Aber Sheeran

os.system在Docker中的坑

起笔自
所属文集: 程序杂记
共计 803 个字符
落笔于

最近在忙项目的同时,也想把自己的小工具用自己的index.py重写一下。为了从实践中完善index.py。

但在尝试使用docker运行index.py的时候,出了问题。

问题

众所周知,docker容器在正常终止时会向主进程(pid 1)发送一个SIGTERM信号。一般来说,程序是能正常接收这个信号,并且退出的。

但……在index.py中偏偏不行!

原因

众所周知,Python的os.system调用的是C函数system

它的执行过程可以用三个词概括:fork、exec、wait。

这里会出现一个问题,它不仅会阻塞调用它的程序,并且在所执行的程序执行完成之前,在Python里处理信号的程序将不会被调用。

解决

于是,如何解决,清晰明了。使用下述函数代替代码里的每一处 os.system 即可。

import os
import time
import signal
import subprocess


def exec(*commands):
    process = subprocess.Popen(" ".join(commands), cwd=os.getcwd(), shell=True)

    def sigterm_handler(signo, frame):
        process.terminate()
        process.wait()

    signal.signal(signal.SIGTERM, sigterm_handler)

    while process.poll() is None:
        time.sleep(1)
    return process.returncode

反思

不要滥用os.system,尽量以subprocess代替。

Python官方诚不欺我。😭

如果你觉得本文值得,不妨赏杯茶
加速Python的asyncio
漂亮的 Windows Terminal