Lui*_* T. 4 bash docker dockerfile docker-compose
我有一个 docker-compose.yml 启动多个容器。其中之一使用 Dockerimage 文件来安装该容器中所需的所有内容。
我想添加一个每次等待中断信号 0、9 和 137 时运行的脚本。
现在,我尝试将脚本作为 Dockerimage 文件中的入口点运行,但似乎不起作用。
这是 Dockerimage 文件的内容:
RUN apt-get update && [...]
WORKDIR "/application"
ENTRYPOINT ["/bin/bash", "-c", "/application/scripts/cl.sh"]
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?我需要使用以下命令重建容器吗?
docker-compose build
Run Code Online (Sandbox Code Playgroud)
这是bash脚本cl.sh的内容
#!/bin/bash
echo "HELLO HELLO HELLO HELLO"
trap 'echo "Exiting with a 137 signal."' 137 0 9
Run Code Online (Sandbox Code Playgroud)
目前该脚本的唯一目的是测试所有功能。
是的,有可能实现您想要的,但在呈现相应的代码之前,我必须对您的问题的代码进行评论,其中包含一些问题:
\n\n该行trap \'echo "Exiting with a 137 signal."\' 137 0 9
不正确,因为 137 不是有效的信号编号(例如,请参阅维基百科关于信号的文章))。
也许您刚刚遇到了 137,因为它是与信号9对应的退出代码(假定 137 = 128 + 9,请参阅bash 文档中的附录)。)
0 (EXIT) 和 9 (KILL) 是有效的信号编号,但实际上最好只捕获 2 (INT) 和 15 (TERM),如这个 SE/Unix 答案中所建议的中所建议的。
\n\n事实上,虽然 INT 和 TERM 信号可用于“优雅终止”,但 KILL 信号意味着必须立即终止进程,如下所述man trap
:
\n为 SIGKILL 或 SIGSTOP 设置陷阱会产生未定义的结果。\n [\xe2\x80\xa6] 某些历史实现在语法上接受捕获 SIGKILL 或 SIGSTOP,但它没有任何效果。便携式 POSIX 应用程序无法尝试捕获这些信号。
\n
在入口点脚本的末尾设置陷阱是一个糟糕的策略,因为它在这个地方没有用。相反,我建议您定义一个清理函数(其中最后一条指令是exit
),然后在脚本开头对此函数设置陷阱,然后运行您的(非终止)应用程序。
因此,有以下概念验证:
\n\n\n\n\nDockerfile
\n
FROM debian:latest\nWORKDIR /app\n\nCOPY entrypoint.bash ./\nENTRYPOINT ["/bin/bash", "./entrypoint.bash"]\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n\n入口点.bash
\n
#!/bin/bash\n\ncleanup() {\n echo "Cleaning up..."\n exit\n}\n\ntrap cleanup INT TERM\n\nwhile :; do\n echo "Hello! ${SECONDS} secs elapsed..."\n sleep 1s\ndone\n
Run Code Online (Sandbox Code Playgroud)\n\n要测试它,您只需运行:
\n\n$ docker build -t test-trap .\n$ docker run -d --name=TEST-TRAP test-trap\n # wait a few seconds\n$ docker stop TEST-TRAP\n$ docker logs -f TEST-TRAP\nHello! 0 secs elapsed...\nHello! 1 secs elapsed...\nHello! 2 secs elapsed...\nHello! 3 secs elapsed...\nCleaning up...\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
4751 次 |
最近记录: |