如何在Dockerfile中为Docker容器设置bash别名?


85

我是Docker的新手。我发现我们可以使用Dockerfile中的ENV指令设置环境变量。但是,如何在Dockerfile中为长命令设置bash别名?


别名已被认为在长一段时间内已被弃用。使用功能。不再有任何需要不断使用的别名。这些方法从80年代末开始持续了这么长时间如何?
威廉·珀塞尔

19
因为它们既方便又简单。
亚瑟

13
@WilliamPursell也许您应该解释一下如何使用函数。
埃里克·德拉克鲁兹

2
别名简单,方便,易碎且容易出错。功能同样易于使用,但提供了更大的灵活性和健壮性。关于如何使用它们,有很多资源可用。
威廉·珀塞尔

Answers:


141

基本上就像您经常做的那样,将其添加到用户的.bashrc

FROM foo
RUN echo 'alias hi="echo hello"' >> ~/.bashrc

和往常一样,这仅适用于交互式外壳:

docker build -t test .
docker run -it --rm --entrypoint /bin/bash test hi
/bin/bash: hi: No such file or directory
docker run -it --rm test bash
$ hi
hello

对于非交互式外壳,您应该创建一个小脚本并将其放在路径中,即:

RUN echo -e '#!/bin/bash\necho hello' > /usr/bin/hi && \
    chmod +x /usr/bin/hi

如果您的别名使用参数(即hi Jim-> hello Jim),则只需添加"$@"

RUN echo -e '#!/bin/bash\necho hello "$@"' > /usr/bin/hi && \
    chmod +x /usr/bin/hi

谢谢你能提供一个非交互式外壳的例子吗?我正在寻找ENTRYPOINT和CMD来解决这个问题
c24b

5
Bash别名仅在交互式shell中起作用。只需创建一个小的Shell脚本,然后将其放在您的路径中,就和别名一样。用一个简单的示例更新了答案。
Erik Dannenberg

1
注意:在stackoverflow.com/a/8467449中,您应该使用printf而不是echo来确保更一致的行为。所以printf'#!/ bin / bash \ necho hello'> / usr / bin / hi chmod + x / usr / bin / hi
barraq

2
喜欢shell脚本的想法。想要添加别名,但这要好得多。谢谢。
Blizz

3
对于多个参数转义,应使用“ $ @”而不是$ *。参见unix.stackexchange.com/questions/248464/…–
gnou

14

要创建现有命令的别名,还可以使用ln -s

ln -s $(which <existing_command>) /usr/bin/<my_command>


6
我不会将其称为别名..这是一个软链接/符号链接。别名的方便之处在于您可以将参数传递给命令,就像alias ll='ls -lh'使用符号链接无法做到的那样。
qwertz

3

如果只想在Dockerfile中使用别名,而不是在容器中使用别名,那么最简单的方法就是ENV声明:

ENV update='apt-get update -qq'
ENV install='apt-get install -qq'

RUN $update && $install apt-utils \
    curl \
    gnupg \
    python3.6

并以已描述的方式用于容器中:

 RUN printf '#!/bin/bash \n $(which apt-get) install -qq $@' > /usr/bin/install
 RUN chmod +x /usr/bin/install

大多数时候,我只是在构建阶段使用别名,而不是将其放入容器中,因此第一个示例对于每天的使用来说更加快捷,清晰和简单。


2

我刚刚将此添加到我的app.dockerfile

# setup aliases
ADD ./bashrc_alias.sh /usr/sbin/bashrc_alias.sh
ADD ./initbash_profile.sh /usr/sbin/initbash_profile
RUN chmod +x /usr/sbin/initbash_profile
RUN /bin/bash -C "/usr/sbin/initbash_profile"

并在initbash_profile.sh其中添加我的自定义别名,而无需获取.bashrc文件的来源。

# add the bash aliases
cat /usr/sbin/bashrc_alias.sh >> ~/.bashrc

工作了请客!

另一个选择是仅从容器外部使用“ docker exec -it命令”,然后仅使用自己的.bashrc或.bash_profile(无论您喜欢什么)

例如。 docker exec -it docker_app_1 bash


1

您可以在Dockerfile中使用入口点,但不适用于别名:

ADD dev/entrypoint.sh /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]

您的 entrypoint.sh

#!/bin/bash
set -e

function dev_run()
{

}

export -f dev_run

exec "$@"

(快速复制/粘贴,对不起)


请注意,某些Docker映像可能已经覆盖了默认入口点(例如phusion基本映像)。
Thomas Decaux

1

我认为最简单的方法是将文件装载到包含别名的容器中,然后指定bash应该在哪里找到它:

docker run \
    -it \
    --rm \
    -v ~/.bash_aliases:/tmp/.bash_aliases \
    [image] \
    /bin/bash --init-file /tmp/.bash_aliases

用法示例:

user@cobalt:~$ echo 'alias what="echo it works"' > my_aliases
user@cobalt:~$ docker run -it --rm -v ~/my_aliases:/tmp/my_aliases ubuntu:18.04 /bin/bash --init-file /tmp/my_aliases
root@565e4a1bdcc0:/# alias
alias what='echo it works'
root@565e4a1bdcc0:/# what
it works

0
  1. 编辑此文件〜/ .bash_aliases vi ~/.bash_aliases
  2. 源此文件〜/ .bash_aliases source ~/.bash_aliases
  3. 完成。

每次启动docker容器都可以,但是别名不会在下一次保留。如果您不介意每次解决方案都可以重新添加它们的话。
mikoop

0

使用了上述某些解决方案,但仍无法识别别名。

我试图设置别名,并在以后的Dockerfile步骤中以及运行时在容器中使用它们。

RUN echo "alias model-downloader='python3 ${MODEL_DL_PATH}/downloader.py'" >> ~/.bash_aliases && \
    echo "alias model-converter='python3 ${MODEL_DL_PATH}/converter.py'" >> ~/.bash_aliases && \
    source ~/.bash_aliases

# Download the model
RUN model-downloader --name $MODEL_NAME -o $MODEL_DIR --precisions $MODEL_PRECISION;

对我来说,解决方案是使用保存文件夹路径的ENV变量,然后添加确切的可执行文件。我也可以使用ARG,但是对于我的更多场景,在构建阶段以及稍后的运行时都需要使用别名。

将ENV变量与bash脚本结合使用,该bash脚本在依赖项被触发并设置bash源,设置更多env变量并允许其他命令通过时运行。


每条RUN指令都在新的外壳中执行,因此在您的示例中,当您尝试使用别名时不再加载别名文件。
Erik Dannenberg

100%@ErikDannenberg感谢您的评论,也提醒我我需要对此进行更新-我发现了一个解决方案,它非常像您建议的那样。
alanionita

0

这是一个Bash函数,用于在您交互使用的每个容器中使用别名。

ducker_it() {
    docker cp ~/bin/alias.sh "$1":/tmp
    docker exec -it "$1" /bin/bash -c "[[ ! -f /tmp/alias.sh.done ]] \
        && [[ -w /root/.bashrc ]] \
        && cat /tmp/alias.sh >> /root/.bashrc \
        && touch /tmp/alias.sh.done"
    docker exec -it "$1" /bin/bash
}

之前需要执行的步骤:

grep ^alias ~/.zshrc > ~/bin/alias.sh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.