首页 > 解决方案 > Bash:等待图像在 dockerhub 中可用

问题描述

我正在尝试创建一个 bash 脚本,如果存在,它将从 docker hub 下载图像,否则它将等待 5 分钟然后退出

#!/bin/sh

waitForDockerImage=0
res='Error response from daemon'
while [[ "${res}" == *"Error response from daemon"* ]]; do
    echo $res
    res=$(docker pull node/base-alpine:test)
    echo $res
    waitForDockerImage=$(($waitForDockerImage+10))
    if [ $waitForDockerImage -gt 300 ];then
        echo "waited for 5 mins, exiting now.."
        exit
    else
        sleep 1 # wait for 1 the second before check again
    fi
done

此外,while 循环在第一次迭代时运行,但在第二次迭代时失败。对于第 2 次运行

res=Error response from daemon: manifest for Error response from daemon: manifest for not found: manifest unknown: manifest unknown

所以我正在检查 res 是否包含Error response from daemon

标签: bash

解决方案


The error response is written to standard error, not standard output. It works the first time because you manually set res, rather than failing to capture standard error from docker. Change the assignment in the loop to

res=$(docker pull node/base-alpine:test 2>&1)

Better yet, ignore the standard error and test the exit status of docker pull.

i=0
while :;do
    docker pull node/base-alpine:test 2>/dev/null && break
    if [ "$i" -gt 300 ]; then
        printf 'Waited 5 minutes, exiting now\n' >&2
        exit 1
    fi
    i=$((i+1))
    sleep 1
done

Since you are using bash, though, it's easy to check if 5 minutes have passed without using a counter as a proxy.

SECONDS=0
while :; do
    docker pull node/base-alpine:test 2>/dev/null && break
    if (( $SECONDS > 300 )); then
        printf 'Waited 5 minutes, exiting now\n' >&2
        exit 1
    fi
    sleep 1
done

SECONDS is a special variable in bash whose value is effectively incremented once per second.


推荐阅读