Docker中的Subshel​​l命令

时间:2018-09-11 23:25:10

标签: docker

在构建过程中,我需要调用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的路径。我已经尝试过使用subshel​​l了

$ 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的路径吗?

3 个答案:

答案 0 :(得分:1)

使用-exec选项可以执行某些操作。

find . -name zipalign -exec bash -c '"$0"' {} \;

在您的示例中:

docker run nathansamson/flutter-builder-docker:v0.7.3 find . -name zipalign -exec bash -c '"$0"' {} \;

答案 1 :(得分:1)

在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"]

另一种可行的方法是使用build参数或环境变量保存版本号。如果这样做,则可以设置一个已知的路径名。

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"]

答案 2 :(得分:-1)

如果没有什么可以给您任何提示,而您只需要找到它,那么find可能会做到。像这样:

find /opt -name zipalign -type f

如果您可以给它一个更具体的起点,而不只是/ opt,那么它将运行得更快。

如果要在一行中执行它(并传递“ -h”),则可以执行以下操作:

$(find /opt -name zipalign -type f) -h