shell 在bash脚本执行过程中与Docker容器交互[在该容器中]

0s7z1bwu  于 2023-02-09  发布在  Shell
关注(0)|答案(1)|浏览(206)

我想在Python脚本的帮助下启动一组Docker容器。为此,我使用了subprocess库。实际上,我正在尝试运行以下Docker命令

docker = f"docker run -it --rm {env_vars} {hashes} {results} {script} {pipeline} --name {project} {CONTAINER_NAME}"

在新终端窗口中。

Popen(f'xterm -T {project} -geometry 150x30+100+350 -e {docker}', shell=True)
# or
Popen(f'xfce4-terminal -T {project} --minimize {hold} -e="{docker}"', shell=True)

容器的CMD看起来像这样,它是一个bash脚本,可以在其中运行其他脚本和函数。

CMD ["bash", "/run_pipeline.sh"]

我尝试做的是在发生故障时(即满足某些条件时)从这些嵌套脚本中的一个特定位置运行一个交互式shell(bash),以便能够调查脚本中的问题,采取措施修复它并继续执行(或者如果无法修复它,则退出)。

if [ $? -ne 0 ]; then
  echo Investigate manually: "$REPO_NAME"
  bash
  if [ $? -ne 0 ]; then exit 33; fi
fi

我希望完全自动地执行这些操作,这样我就不必手动跟踪脚本的运行情况并在需要时执行docker attach...,因为我将同时运行多个这样的容器。
问题是这个"救援" bash进程会立即退出,我不知道为什么,我想应该是tty之类的东西,但是我已经试过很多次了,都没有成功。
我尝试了docker命令的-i-t-d的不同组合,尝试了在使用-d启动container之后立即使用docker attach...,还尝试了直接从终端中的bash启动python脚本(我默认使用的是Pycharm).此外,我尝试使用socatscreenscriptgetty命令(在嵌套的bash脚本中),但是我不知道如何正确地使用它们,所以它也没有很好地结束。在这一点上,我太困惑了,不明白为什么它不工作。
编辑:
添加最小的不可复制(什么是不工作)的例子,我如何启动一个容器。

# ./Dockerfile
FROM debian:bookworm-slim
SHELL ["bash", "-c"]
CMD ["bash", "/run_pipeline.sh"]

# run 'docker build -t test .'
# ./small_example.py
from subprocess import Popen

if __name__ == '__main__':
    env_vars = f"-e REPO_NAME=test -e PROJECT=test_test"
    script = f'-v "$(pwd)"/run_pipeline.sh:/run_pipeline.sh:ro'
    docker = f"docker run -it --rm {env_vars} {script} --name test_name test"

    # Popen(f'xterm -T test -geometry 150x30+100+350 +hold -e "{docker}"', shell=True).wait()
    Popen(f'xfce4-terminal -T test --hold -e="{docker}"', shell=True).wait()
# ./run_pipeline.sh

# do some hard work

ls non/existent/path

if [ $? -ne 0 ]; then
  echo Investigate manually: "$REPO_NAME"
  bash
  if [ $? -ne 0 ]; then exit 33; fi
fi

看起来问题可能出在run_pipeline.sh脚本中,但我不想在这里上传它,它比我之前描述的更混乱。但我会说,无论如何,我正在尝试运行这个东西-https://github.com/IBM/D2A
所以我只是想要一些关于tty的东西的建议,我可能错过了。

kkbh8khc

kkbh8khc1#

使用input和tty运行初始容器detached。

docker run -dit --rm {env_vars} {script} --name test_name test

监视输出的容器日志,然后附加到它。
下面是一个快速脚本示例(本例中没有tty,只是因为演示使用echo进行输入)

#!/bin/bash

docker run --name test_name -id debian \
  bash -c 'echo start; sleep 10; echo "reading"; read var; echo "var=$var"'

while ! docker logs test_name | grep reading; do
  sleep 3
done

echo "attach input" | docker attach test_name

完成后的完整输出:

$ docker logs test_name
start
reading
var=attach input

整个过程更容易通过Docker Python SDK来控制,而不是在python和Docker之间有一层shell。

相关问题