You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何终止父脚本input.sh及其调用的Docker容器所有进程?

如何同时终止input.sh脚本及Docker容器的所有进程

好的,我来帮你解决这个问题——要同时终止input.sh脚本和它启动的Docker容器的所有进程,我们可以分脚本内自动处理手动事后处理两种场景来操作:

一、在input.sh中添加自动终止逻辑(推荐)

这种方式能让脚本在收到终止信号(比如Ctrl+C)时,自动先停止Docker容器,再退出自身,无需手动查找PID。你可以修改input.sh如下:

#!/bin/sh
input_variable_docker=folder

# 定义清理函数:停止容器并退出脚本
cleanup() {
    echo "正在停止Docker容器..."
    # 停止容器,忽略错误(比如容器已经提前退出)
    docker stop "$CONTAINER_ID" > /dev/null 2>&1
    echo "脚本已终止"
    exit 0
}

# 捕获常见的终止信号(Ctrl+C触发SIGINT,kill命令触发SIGTERM)
trap cleanup SIGINT SIGTERM

# 后台启动容器并记录容器ID(原来的前台运行会阻塞脚本,所以加-d让它后台跑)
CONTAINER_ID=$(docker run -d -t --rm -v /mnt/data/:/home/user/data/ -e INPUT_IMAGE="$input_variable_docker" my_process /home/desuser/processing_scripts/run_script_docker.sh)

# 可选:如果需要脚本一直等待容器完成任务再退出,加上这行
docker wait "$CONTAINER_ID"

使用方式

运行修改后的input.sh后,当你按下Ctrl+C,或者用kill <脚本PID>终止脚本时,脚本会自动调用cleanup函数停止容器,然后自身退出,完全清理所有相关进程。

二、手动终止已运行的脚本和容器

如果脚本已经在运行,你可以手动获取PID并一次性终止:

  1. 获取input.sh的PID

    SCRIPT_PID=$(pgrep -f input.sh)
    
  2. 获取对应的Docker容器ID
    可以根据镜像名过滤(你的镜像是my_process):

    CONTAINER_ID=$(docker ps --filter "ancestor=my_process" -q)
    
  3. 同时终止容器和脚本

    docker stop "$CONTAINER_ID" && kill "$SCRIPT_PID"
    

补充说明

  • Docker容器停止时,会先向容器内的PID 1进程发送SIGTERM信号,如果进程没有在10秒内退出,会发送SIGKILL强制终止,容器内的所有子进程也会被自动清理(因为Docker的PID命名空间特性)。
  • 如果你的容器是前台运行的(没加-d),脚本会被容器进程阻塞,这时候脚本的PID就是父进程,容器进程是它的子进程,你可以用pkill -P <脚本PID>来杀死所有子进程,再杀死脚本本身:
    SCRIPT_PID=$(pgrep -f input.sh)
    pkill -P "$SCRIPT_PID" && kill "$SCRIPT_PID"
    

内容的提问来源于stack exchange,提问作者sylar_80

火山引擎 最新活动