如果它正在运行,则停止并删除docker容器

Rob*_*_UK 54 bash containers docker

我希望实际停止并删除一个docker容器,如果它正在运行.这是一个构建脚本.

以下面的例子为例.如何在bash脚本中的NAMES列下停止并删除docker容器"rabbitmq".

docker ps

CONTAINER ID        IMAGE             COMMAND                  CREATED             STATUS              PORTS                   NAMES
9909a5e2856f        rabbitmq-image   "/docker-entrypoint.s"   11 minutes ago      Up 11 minutes       0.0.0.0:5672->5672/tcp, rabbitmq
8990dd1fe503        redis-image      "/entrypoint.sh redis"   6 weeks ago         Up 4 days           0.0.0.0:32770->6379/tcp redis
etc 
Run Code Online (Sandbox Code Playgroud)

以下命令将删除容器并执行即将发生的操作

docker stop rabbitmq && docker rm -f rabbitmq
Run Code Online (Sandbox Code Playgroud)

然而它将它梳理成我想知道的脚本?我认为它看起来像这样.

#!/bin/bash

if [ /*docker ps check some value */ ]; then
   docker stop rabbitmq && docker rm -f rabbitmq
fi
Run Code Online (Sandbox Code Playgroud)

Joh*_*rop 125

您可能已经注意到,如果容器不存在或未运行docker stop,则docker rm退出时会显示状态代码,表示失败.这会导致您的构建失败.

如果您可以处理构建日志中的错误消息,您可以执行以下小技巧来防止shell命令失败:

docker stop rabbitmq || true && docker rm rabbitmq || true
Run Code Online (Sandbox Code Playgroud)

在其中一个docker命令失败的情况下,true调用它总是退出,状态代码表示成功.

  • 这很棒!Docker应该提供一个标志来忽略stop和rm上的错误...... (5认同)
  • 当容器已经被移除时,这将产生来自守护程序的错误响应:no such id:Rabbitmq。 (2认同)
  • @anubhava:正确.正如答案中已经提到的:"技巧"是忽略docker命令的返回值.如果您需要一个没有错误消息的"干净"解决方案,您需要检查容器是否存在. (2认同)

nco*_*lan 23

我有一个类似的问题,但不喜欢接受的答案,因为它抑制了命令的所有错误,而不仅仅是"未找到"错误.

但是,docker ps -q --filter "name=rabbitmq"如果实际存在该名称的容器,则仅生成输出,因此如果命令输出一个空字符串,我会想到:

docker ps -q --filter "name=rabbitmq" | grep -q . && docker stop rabbitmq && docker rm -fv rabbitmq
Run Code Online (Sandbox Code Playgroud)

以下命令对测试过滤器定义也很有用:

docker ps -q --filter "name=rabbitmq" | grep -q . && echo Found || echo Not Found
Run Code Online (Sandbox Code Playgroud)

我的实际用例是定义一对Ansible任务,从先前任务中生成的名称列表中删除所有当前存在的容器(无论是否运行):

- name: Check for containers that actually exist
  shell: 'docker ps -aq --filter "name={{ item }}"'
  with_items:
    - '{{ previous_command.stdout_lines }}'
  register: found_containers

- name: Remove the containers found by the above command
  shell: 'docker stop {{ item.item }} && docker rm -fv {{ item.item }}'
  with_items: '{{ found_containers.results }}'
  when: item.stdout
Run Code Online (Sandbox Code Playgroud)

  • 我觉得使用`docker ps -aq ...`很有用.`-a`选项意味着它还将查找存在但当前未运行的容器. (3认同)

art*_*rtm 21

@ncoghlan 的答案的一个变体:

# stop runnin container(s)
docker ps -q --filter "name=$name" | xargs -r docker stop
# remove existing container(s)
docker ps -aq --filter "name=$name" | xargs -r docker rm
Run Code Online (Sandbox Code Playgroud)
  • pipeline intoxargs是使用输出构建命令的惯用方法
  • xargs -r当不存在匹配的容器时避免运行 docker 命令
  • 首先docker ps找到所有匹配的正在运行的容器
  • 第二个docker ps找到所有匹配的容器,即使没有运行
  • 单独的命令确保容器被删除,即使它没有运行


anu*_*ava 12

您可以使用:

app="rabbitmq"
if docker ps | awk -v app="$app" 'NR > 1 && $NF == app{ret=1; exit} END{exit !ret}'; then
  docker stop "$app" && docker rm -f "$app"
fi
Run Code Online (Sandbox Code Playgroud)
  • awk命令app从BASH的变量中获取命令行var$app
  • NR>1docker ps命令跳过第一个标题行.
  • $(NF) == app比较最后一列NAMES是否等于app变量

  • 这是最完整的答案.添加`||的问题 true`是它仍然存在一个带有docker错误的bash脚本.通过检查容器的docker容器列表,您可以保证只调用stop和rm(如果存在),消除错误并允许脚本运行所需的所有容器命令. (2认同)

Rob*_*_UK 10

现在已经使用了docker一段时间了.这是我停止和删除docker容器的首选方法.

docker rm -f container_name || true
Run Code Online (Sandbox Code Playgroud)

  • docker rm -f container_name&> / dev / null && echo'已删除的旧容器' (5认同)

ive*_*r56 7

# Stop and remove containers with names like "rabbitmq" and "rabbitmq123" if they exist
CONTAINER_NAME="rabbitmq"
OLD="$(docker ps --all --quiet --filter=name="$CONTAINER_NAME")"
if [ -n "$OLD" ]; then
  docker stop $OLD && docker rm $OLD
fi
Run Code Online (Sandbox Code Playgroud)


DS.*_*DS. 5

我建议在 bash 中使用这个咒语:

( docker stop $CONTAINER > /dev/null && echo Stopped container $CONTAINER && \
  docker rm $CONTAINER ) 2>/dev/null || true
Run Code Online (Sandbox Code Playgroud)

它总是以 0 退出,如果容器没有运行则不会抱怨,并且Stopped container $CONTAINER如果容器确实停止则打印。