我如何才能 运行 一个在失败后不退出直到成功的命令?

How Can I Run A Command That Does Not Exit Upon Failure Until It Succeeds?

我有一个 Docker 容器 运行ning HBase 有关它的更多详细信息,请参阅 here。基本上,HBase 需要大约 30 秒才能启动。

显然我有其他容器依赖于这个容器。其中之一,在 docker-entrypoint.sh 中,我基本上是这样做的:

#!/bin/bash

/path/to/command argument

while [ $? -ne 0 ]; do
  sleep 2;
  /path/to/command argument
done

这里的问题是 /path/to/command 是部署网络服务器的东西,它将与 HBase 容器交互。如果成功,它会阻塞当前进程(这很好,因为它在容器中),但同样,如果失败,它会打印堆栈跟踪但不会退出并返回一些 -ne 0 代码(实际上,根本不退出)。事实上,如果它退出 --restart=always 将处理它。

所以,我的问题是,我怎样才能一直重试直到成功,基本上不退出并返回一些失败代码?从 Docker 容器中退出也是一个选项,这样它就可以一直重启直到成功。目前,我没有机会修改不退出代码退出。

更新:

我不得不这样做:

#!/bin/bash

tmp=$(mktemp)
/path/to/command args 2> "$tmp" &

while true; do
  sleep 5;
  if [ -s "$tmp" ]; then
    exit
  fi
done

基本上,我必须在后台 运行 它以便上面的脚本继续执行(path/to/command 是一个 UI 阻塞命令 - 例如 listen服务器的 - 它在成功时不会退出 - 它会监听 - 也不会在失败时退出 - 它应该有,这就是我问这个问题的原因 -)。

所以为了 Docker 容器不退出,我不得不添加一个 while true; 循环,我在其中检查 $tmp 中是否有错误。如果有,我就直接exit.

更新 2:

我将 bash 脚本更改为:

#!/bin/bash

/path/to/command args &

while true; do
  sleep 10;
  
  response=$(curl --write-out %{http_code} --silent --output /dev/null http://localhost);

  if [ "$response" != "200" ]; then
    exit
  fi
  
done

因为我的容器正在部署一个网络服务器,我至少在启动它之后在主线程中监视它的状态。还有改进的空间。

您可以尝试将 stderr 重定向到一个文件,然后检查该文件是否为空:

tmp=$(mktemp)
/path/to/command argument 2> "$tmp"

# Run code until "$tmp" is empty
until [ -s "$tmp" ]; do
  sleep 2
  /path/to/command argument 2> "$tmp"
done

rm "$tmp"