【问题标题】:docker exec command doesn't return after completing executiondocker exec 命令在完成执行后不返回
【发布时间】:2016-06-16 03:04:13
【问题描述】:

我基于一个包含“run.sh”文件的图像启动了一个 docker 容器。在 shell 脚本中,我使用 docker exec 如下所示

docker exec <container-id> sh /test.sh

test.sh 完成执行,但 docker exec 直到我按 ctrl+C 才返回。结果,我的 shell 脚本永远不会结束。任何可能导致此问题的指针。

【问题讨论】:

  • 你找到解决办法了吗?
  • 这里有同样的问题。有什么解决办法吗?
  • 没有找到任何解决方案。
  • 哪个版本的 docker?您之前是否使用不同的脚本/命令在同一个容器上执行过?
  • 同样的问题没有任何解释也没有办法调试它。有人可以帮我吗?

标签: docker exec


【解决方案1】:

我可以通过添加 -it 参数让它工作:

docker exec -it &lt;container-id&gt; sh /test.sh

【讨论】:

【解决方案2】:

我的工作就像这个命令的魅力。也许您只是忘记了二进制文件的路径(/bin/sh)?

docker exec 7bd877d15c9b /bin/bash /test.sh

文件位置

/test.sh

文件内容:

#!/bin/bash
echo "Hi"
echo
echo "This works fine"
sleep 5
echo "5"

输出:

ArgonQQ@Terminal ~  docker exec 7bd877d15c9b /bin/bash /test.sh
Hi

This works fine
5
ArgonQQ@Terminal ~ 

【讨论】:

  • 是的,它适用于大多数情况。为了排除我的 test.sh 有问题,我在 test.sh 文件的末尾添加了一个 echo 语句,它也被打印出来了。 docker exec 由于某种原因没有返回。
  • 这个答案既没有回答“什么可能导致这种情况”的问题,也没有提供解决方案。
【解决方案3】:

好的,我明白了。

码头工人停止 a590382c2943

docker 启动 a590382c2943

然后就可以了。

docker exec -ti a590382c2943 echo "5"

会立即返回,加不加-it也没用

实际上,在我的程序中,deamon 有 std 输入和 std 输出,std err。所以我改变了我的 python 守护程序,如下所示,事情就像一个魅力:

if __name__ == '__main__':
    # do the UNIX double-fork magic, see Stevens' "Advanced
    # Programming in the UNIX Environment" for details (ISBN 0201563177)

    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            os._exit(0)
    except OSError, e:
        print "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
        os._exit(0)
    # decouple from parent environment
    #os.chdir("/")
    os.setsid()
    os.umask(0)
    #std in out err, redirect
    si = file('/dev/null', 'r')
    so = file('/dev/null', 'a+')
    se = file('/dev/null', 'a+', 0)
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())
    # do second fork
    while(True):
        try:
            pid = os.fork()
            if pid == 0:
                serve()
            if pid > 0:
                print "Server PID %d, Daemon PID: %d" % (pid, os.getpid())
                os.wait()
                time.sleep(3)
        except OSError, e:
            #print "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
            os._exit(0)

【讨论】:

    【解决方案4】:

    我的案例是一个包含内容的脚本 a.sh
    喜欢

    php test.php &
    

    如果我像这样执行它

    docker exec contianer1 a.sh
    

    它也再也没有回来。

    经过半天的谷歌搜索和尝试
    将 a.sh 更改为

    php test.php >/tmp/test.log 2>&1 &
    

    有效!

    所以它似乎与标准输入/输出/错误有关。

    >/tmp/test.log 2>&1
    

    请尝试。

    请注意,我的test.php是一个死循环脚本,它监控指定进程,如果进程宕机,它会重新启动它。所以 test.php 永远不会退出。

    【讨论】:

      【解决方案5】:

      here 所述,当您的进程保持标准输出或标准错误打开时,就会发生这种“挂起”行为。

      为防止这种情况发生,每个长时间运行的进程应该:

      1. 后台执行,并且
      2. 关闭两者 stdout 和 stderr 或将它们重定向到文件或/dev/null

      因此,我会确保容器中已经运行的所有进程以及传递给docker exec 的脚本都符合上述规定。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-17
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        • 2015-06-07
        • 2013-09-07
        • 1970-01-01
        • 2014-12-12
        相关资源
        最近更新 更多