我在docker上运行这个命令来安装一些android sdk组件:
RUN mkdir ${ANDROID_HOME} && wget --output-document=android-sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip
&& unzip android-sdk.zip -d ${ANDROID_HOME}
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} --list
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "build-tools;25.0.1"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "build-tools;28.0.3"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "build-tools;29.0.2"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "platform-tools"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "platforms;android-25"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "platforms;android-28"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "platforms;android-30"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "extras;android;m2repository"
&& echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "extras;google;google_play_services"
&& ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "ndk;${ANDROID_NDK_VERSION}"
&& ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "cmake;3.10.2.4988404"
&& yes | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} --update
由于这是一个docker图像,我必须在同一个命令中运行所有内容,否则图像将有太多额外的层,并占用太多空间。
问题是,由于μ不可靠的互联网,我很可能会因为安装的其中一个组件的标签不匹配,这让我不得不再次运行该过程。我必须构建我的docker镜像30多次,才能让它成功地执行所有命令。
有没有办法在android sdk中重试标签不匹配?
我还想过试着单独运行每一行,但仍然在一个大命令内。
也许
while true; do
subcommand1
if [ $? -eq 0 ]; then
break
fi
sleep 1
done
while true; do
subcommand2
if [ $? -eq 0 ]; then
break
fi
sleep 1
done
通过创建一个执行while
循环的函数,在.sh文件上这会很容易,但如果我想在Dockerfile中执行所有操作呢?
有人有更好的主意吗?
免责声明:我不知道你的命令在做什么(除了下载android sdk(,所以你可能需要稍微修改我的代码才能让它工作此外,您的图像可能不包括timeout
首先,我会将脚本移动到一个单独的文件中,与Dockerfile
位于同一目录中,然后像这样执行:
COPY ./build.sh .
RUN chmod +x ./build.sh && ./build.sh
现在在脚本中,您可以在继续之前检查每一行的输出:
#!/bin/bash
url="https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip"
mkdir ${ANDROID_HOME}
until (
wget --output-document=android-sdk.zip "$url" &&
unzip android-sdk.zip -d ${ANDROID_HOME}
); do
sleep 1
done
args=(
"--list"
"build-tools;25.0.1"
"build-tools;28.0.3"
"build-tools;29.0.2"
"platform-tools"
"platforms;android-25"
"platforms;android-28"
"platforms;android-30"
"extras;android;m2repository"
"extras;google;google_play_services"
)
# you may need to modify this slightly!
for arg in "${args[@]}";
do
until ( echo y | ${SDKMANAGER} --sdk_root=${ANDROID_HOME} "$arg" ); do
sleep 5
done
done
最好设置超时,这样您的构建就不会陷入无限循环。我不想在脚本中添加两个单独的检查,而是将其添加到Dockerfile
:
# might need adjusting
ARG MAX_TIMEOUT=60
COPY ./build.sh .
RUN chmod +x ./build.sh && timeout -k $MAX_TIMEOUT ./build.sh
我建议将其用作主项目的Base Image
,而不是将其包含在同一个Dockerfile
中。这样,如果你需要修改你的项目的Dockerfile
并重建,你就不必每次都重建android sdk。