如何在Dockerfile中运行bash函数

21

我在/root/.profile中定义了一个bash函数nvm。当我在RUN步骤中调用它时,docker build找不到该函数。

RUN apt-get install -y curl build-essential libssl-dev && \
    curl https://raw.githubusercontent.com/creationix/nvm/v0.16.1/install.sh | sh
RUN nvm install 0.12 && \
    nvm alias default 0.12 && \
    nvm use 0.12

错误是

Step 5 : RUN nvm install 0.12
 ---> Running in b639c2bf60c0
/bin/sh: nvm: command not found

我成功地通过用bash -icnvm包装起来来调用它,这将加载/root/.profile

RUN bash -ic "nvm install 0.12" && \
    bash -ic "nvm alias default 0.12" && \
    bash -ic "nvm use 0.12"

上述方法运行正常,但是它有一个警告。

bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell

我想知道是否有一种更简单、更干净的方法来直接调用bash函数,就像调用普通二进制文件一样,而不需要使用bash -ic包装?也许像这样的东西:

RUN load_functions && \
    nvm install 0.12 && \
    nvm alias default 0.12 && \
    nvm use 0.12

运行 bash -c 'nvm install 0.12 && nvm alias default 0.12 && nvm use 0.12' 应该可以解决问题。这对你有用吗?(我不太确定,因为我不了解你的容器的详细情况) - hek2mgl
它可以正常工作。但我正在寻找更好的解决方案。 - Quanlong
好的,检查我的答案。使用Shell脚本是最干净的方法。 - hek2mgl
你到目前为止还没有接受我的答案。你所说的“更好”的解决方案是什么意思? - hek2mgl
NVM并不适用于Docker。您真的想在一个容器中使用两个Node.js吗? - Franklin Yu
1个回答

19

Docker的RUN不在shell中启动命令。这就是为什么shell函数和shell语法(例如cmd1&&cmd2)不能直接使用的原因。您需要显式地调用shell:

RUN bash -c 'nvm install 0.12 && nvm alias default 0.12 && nvm use 0.12'

如果您害怕冗长的命令行,请将这些命令放入一个shell脚本中,并使用RUN调用该脚本:

script.sh

#!/bin/bash

nvm install 0.12 && \
nvm alias default 0.12 && \
nvm use 0.12

并将其变为可执行文件:

chmod +x script.sh
在 Dockerfile 中添加以下内容:
RUN /path/to/script.sh

我需要以一些不同的步骤运行 nvm。当命令格式化为多行时,bash -c 的正确引用似乎很难控制。 - Quanlong
1
这就是为什么我建议使用一个 shell 脚本。 - hek2mgl
我不明白为什么你需要多个脚本。你能详细说明一下吗?一旦我理解了,我可能会提出建议。 - hek2mgl
7
这与我从文档得到的不一样:“RUN <command>shell形式,命令在shell中运行,默认情况下在Linux上是/bin/sh -c,在Windows上是cmd /S /C)。" - Franklin Yu
1
是的,我不确定这个答案是否正确... 我的印象是每个 RUN 命令在一个子 shell 中执行其内容。 - Alexander Mills
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接