在构建过程中,我需要调用zipalign
,它位于我正在使用的docker容器中的某个路径上:
$ docker run nathansamson/flutter-builder-docker:v0.7.3 find . -iname zipalign
./opt/android-sdk-linux/build-tools/28.0.1/zipalign
如果更新了docker容器并且有一个新的android sdk,则此路径可以更改。例如,这可能是未来的道路:
$ docker run nathansamson/flutter-builder-docker:v0.9.9 find . -iname zipalign
./opt/android-sdk-linux/build-tools/42.0.0/zipalign
因此,而不是硬编码调用
docker run nathansamson/flutter-builder-docker:v0.7.3 \
/opt/android-sdk-linux/build-tools/28.0.1/zipalign -h
我想要一个通用的解决方案,自动找到zipalign的路径。我用子shell试了一下
$ docker run nathansamson/flutter-builder-docker:v0.7.3 $(find . -iname zipalign) -h
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:348: starting container process caused "exec: \"-h\":
executable file not found in $PATH": unknown.
ERRO[0001] error waiting for container: context canceled
并使用文件夹的通配符:
$ docker run nathansamson/flutter-builder-docker:v0.7.3 /opt/android-sdk-linux/build-tools/*/zipalign -h
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:348: starting container process caused "exec:
\"/opt/android-sdk-linux/build-tools/*/zipalign\": stat /opt/android-
sdk-linux/build-tools/*/zipalign: no such file or directory": unknown.
ERRO[0001] error waiting for container: context canceled
所以子shell和通配符在Docker中不起作用。有什么想法,每当我打电话时,我怎么能找到zipalign的路径?
find可以使用-exec
选项执行某些操作。
find . -name zipalign -exec bash -c '"$0"' {} \;
在你的例子中:
docker run nathansamson/flutter-builder-docker:v0.7.3 find . -name zipalign -exec bash -c '"$0"' {} \;
在Dockerfile中,您可以控制整个环境。通常最容易让事情出现在他们的“自然”地方,比如/usr/bin
。您还有一个优势,即在单个Docker镜像中,只安装了一个版本的工具。
我可能会这样做:
RUN for f in $PWD/opt/android-sdk-linux/build-tools/*/*; do \
ln -s $f /usr/local/bin; \
done
CMD ["zipalign", "-h"]
另一种可能有效的方法是使用构建参数或环境变量来保存版本号。如果这样做,那么您可以设置已知的路径名称。
ARG version
RUN curl -LO http://.../android-sdk-linux-${version}.tar.gz \
&& tar xzf android-sdk-linux-${version}.tar.gz \
&& rm -f android-sdk-linux-${version}.tar.gz \
&& cd opt/android-sdk-linux-build-tools \
&& ln -s ${version} current
CMD ["./opt/android-sdk-linux/build-tools/current/zipalign"]
如果没有任何东西可以给你任何提示,你需要找到它,那么find
可能会这样做。就像是:
find /opt -name zipalign -type f
如果你可以给它更具体的起点,而不仅仅是/ opt,那么它将运行得更快。
如果你想在一行中执行它(并传入“-h”),你可以这样做:
$(find /opt -name zipalign -type f) -h