如何运行失败后不退出的命令,直到成功?
Posted
技术标签:
【中文标题】如何运行失败后不退出的命令,直到成功?【英文标题】:How Can I Run A Command That Does Not Exit Upon Failure Until It Succeeds? 【发布时间】:2016-10-08 11:35:59 【问题描述】:我有一个运行HBase
的Docker
容器,有关它的更多详细信息,请参阅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
因为我的容器正在部署一个 Web 服务器,所以我至少在启动它之后在主线程中监控它的状态。仍有改进的余地。
【问题讨论】:
旁注:This 和其他一些人对退出进程提出了相同的问题。 也许能够将stderr重定向到一个文件,然后检查该文件是否为空。 @andlrc 聪明。我会尽快尝试。 您也可以将其作为后台进程运行并加入警报... @Will,我可以将它作为后台进程运行,但不太明白/知道您加入警报的意思。 【参考方案1】:您可以尝试将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"
【讨论】:
当我要再次运行命令时,我是否应该不清除$tmp
?
@HasanCanSaral 2>
应该为您做到这一点。考虑echo 1 > a;echo 2> a; od a;
将输出0000000
意味着它是空的
一个简单的问题,我最终会遇到几个卡住的进程,一个在成功后运行吗?当$tmp
不为空时,我怎么能设法从Docker
container 退出,我认为这是一个更好的选择?
@HasanCanSaral 您的进程将在打印堆栈跟踪时终止,如果他们不这样做,您的代码将如何继续执行?而until
循环会在tmp文件不为空时结束,然后删除文件。然后退出。
问题是他们没有。他们打印堆栈跟踪并挂起,这就是我问这个问题的原因。如果他们要终止,我不会有这个问题,因为 Docker 容器会退出然后重新启动。我不得不像上面那样做(参见编辑后的帖子),但对此不太满意。以上是关于如何运行失败后不退出的命令,直到成功?的主要内容,如果未能解决你的问题,请参考以下文章
如果 errexit 打开,我如何运行可能失败的命令并获取其退出代码?
错误:链接器命令失败,退出代码为 1(使用 -v 查看调用):在 Macbook [重复]
Cocoapods错误:链接器命令失败,退出代码为1(使用-v查看调用)