gpt4 book ai didi

shell - 通过环境传递 bash 代码(用于 docker-compose)

转载 作者:行者123 更新时间:2023-12-02 08:27:06 25 4
gpt4 key购买 nike

我正在尝试处理容器启动的 docker-compose 顺序中的一个已知问题,所以我以一个简单的解决方案结束,有一个脚本来检查环境是否准备好启动命令。

这就是想法,为容器定义一些环境变量:

  • WAIT_COMMAND 应该是一个在 sh 脚本中定义逻辑测试的字符串,它必须返回一个 bool 值
  • START_CMD 一个字符串,其中包含根据 WAIT_COOMAND 结果运行的命令,否则重试直到达到 LOOPS
  • LOOPS 尝试多少次
  • SLEEP两次尝试之间睡多少

在那个例子中,我在启动依赖 ES 数据启动的应用程序之前等待 elasticSearch 响应。

以下脚本将是我在 docker 容器上的入口。

导出的环境变量

WAIT_COMMAND="$(curl --write-out %{http_code} --silent --output /dev/null http://elastic:9200/_cat/health?h=st) == 200"
LOOPS=3
START_CMD="python my_script_depending_on_elastic.py"
SLEEP=2

有了上述 ENV 变量,脚本应该等到 ES 请求返回代码 200

#!/bin/bash

is_ready() {
eval $WAIT_COMMAND
}

# wait until is ready
i=0
while ! is_ready; do
i=`expr $i + 1`
if [ $i -ge $LOOPS ]; then
echo "$(date) - still not ready, giving up"
exit 1
fi
echo "$(date) - waiting to be ready"
sleep $SLEEP
done

#start the script
exec $START_CMD

问题是代码在 is_ready 函数行中不起作用,它不返回 bool 值但尝试将 200 作为命令执行

# ./wait_elastic.sh 
./wait_elastic.sh: line 9: 200: command not found
Fri Jul 3 18:26:43 UTC 2015 - waiting to be ready
./wait_elastic.sh: line 9: 200: command not found
Fri Jul 3 18:26:45 UTC 2015 - waiting to be ready
./wait_elastic.sh: line 9: 200: command not found
Fri Jul 3 18:26:47 UTC 2015 - still not ready, giving up

如何测试curl响应是否正常?

如何将逻辑测试命令指定为:

WAIT_COMMAND="$(curl --write-out %{http_code} --silent --output /dev/null http://elastic:9200/_cat/health?h=st) == 200"

以及如何评估它:

is_ready() {
eval $WAIT_COMMAND
}

?

最佳答案

这个答案是不好的做法。请考虑一种不涉及 eval 的方法。

wait_command='[ $(curl --write-out %{http_code} --silent --output /dev/null http://elastic:9200/_cat/health?h=st) = 200 ]'
is_ready() {
eval "$wait_command"
}

与原始代码的区别:

  • 实际上在正在评估的环境变量中包含 test 命令同义词 [(以前的版本不是合法的 bash 比较语法)。
  • ==(在 POSIX [ 中不是有效运算符)切换到 =(POSIX 允许)。参见 the standards document for the test command .
  • 在分配时从双引号切换到单引号,这样 curl 直到 eval 被调用时才会运行。
  • 引用传递给 eval 的内容,以防止在代码到达 eval 命令之前发生字符串拆分和 glob 扩展。

docker-compose 的上下文中实现它可能如下所示:

app:
command: docker/wait
environment:
- wait_command=[ $(curl --write-out %{http_code} --silent --output /dev/null http://elastic:9200/_cat/health?h=st) = 200 ]
- wait_loops=10
- wait_sleep=30

...使用如下脚本:

#!/bin/bash
s_ready() { eval "$wait_command"; }

# wait until is ready
i=0
while ! is_ready; do
if (( ++i >= wait_loops )); then
echo "$(date) - still not ready, giving up"
exit 1
fi
echo "$(date) - waiting to be ready"
sleep $wait_sleep
done

关于shell - 通过环境传递 bash 代码(用于 docker-compose),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31212547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com