代码之家  ›  专栏  ›  技术社区  ›  mles

docker中的subshell命令

  •  1
  • mles  · 技术社区  · 7 年前

    在构建过程中,我需要调用 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容器并且有了新的AndroidSDK,则此路径可能会更改。例如,这可能是未来的道路:

    $ 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的路径。我试过用地下室

    $ 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 
    

    所以子外壳和通配符在Docker中不起作用。有什么办法让我一打电话就能找到通往zipalign的路吗?

    3 回复  |  直到 7 年前
        1
  •  1
  •   Zack    7 年前

    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"' {} \;
    
        2
  •  1
  •   David Maze    7 年前

    在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"]
    
        3
  •  -1
  •   SiKing    7 年前

    如果没有什么能给你任何提示,而你只需要找到它,那么 find 可能会的。类似于:

    find /opt -name zipalign -type f
    

    如果你能给它更具体的起点,而不是仅仅/opt,那么它会跑得更快。

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

    $(find /opt -name zipalign -type f) -h
    
    推荐文章