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

Docker run bash——初始化文件

  •  0
  • mpen  · 技术社区  · 4 年前

    我试图创建一个别名来帮助调试docker容器。

    我发现了巴什 accepts a --init-file 这个选项应该让我们在进入交互模式之前运行一些命令。

    所以我想我可以

    docker-bash() {
      docker run --rm -it "$1" bash --init-file <(echo "ls; pwd")
    }
    

    但这些命令似乎没有运行:

     % docker-bash c7460dfcab50
    root@9c6f64a9db8c:/#
    

    是逃避问题还是。。发生什么事?

    bash --init-file <(echo "ls; pwd")
    

    在我的主机上的一个终端中单独运行可以正常工作(运行命令启动一个新的bash实例)。

    2 回复  |  直到 4 年前
        1
  •  2
  •   KamilCuk    4 年前

    要点:

    • 这个 <(...) 是bash扩展 process subtitution .
    • 从上面的手册中: Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.
    • 过程替换的工作方式如下:
      • /tmp 或在中创建新的文件描述符 /dev/fd
      • 文件名,或者 /tmp/.something /dev/fd/<number> 代替 <(...) 执行命令时。
      • 例如 echo <(echo 1) /dev/fd/63 .
    • Docker通过创建一个与主机分离的新环境来工作。这意味着:
        • 所以 /dev/fd/* 文件不会被继承。
        • 因此进程无法访问 /tmp/* 来自主机的文件。
    • 所以总结一下 docker run -ti --rm alpine cat <(echo 1) 将不起作用,因为由替换的文件名 < 在docker环境中不可用。

    一个简单的解决方法是:

    docker run -ti --rm alpine sh -c 'ls; pwd; exec sh'
    

    或使用临时文件:

    echo "ls; pwd" > /tmp/tempfile
    docker run -v /tmp/tempfile:/tmp/tempfile bash bash --init-file /tmp/tempfile
    
        2
  •  1
  •   mpen    4 年前

    alias 如果我们重新执行shell,这种情况不会持续。但是,别名可以写入 ~/.bashrc 将重新加载到下一个exec上。因此,

    docker-bash() {
      docker run --rm -it "$1" bash -c $'set -o xtrace; echo "alias ll=\'ls -lAhtrF --color=always\'" >> ~/.bashrc; exec "$0"'
    }
    

    --rm 如果我能正确理解docker的工作原理,我们创建的任何文件都应该清理掉。

    docker-bash() {
    read -r -d '' BASHRC << EOM
    alias ll='ls -lAhtrF --color=always'
    EOM
    docker run --rm -it "$1" bash -c "echo \"$BASHRC\" >> ~/.bashrc; exec \"\$0\""
    }