Makefile多行命令在Docker中无法正常运行

时间:2019-04-07 12:10:51

标签: docker sed makefile subshell

我正在尝试从Markdown编译HTML。我的makefile如下:

MD = pandoc \
    --from markdown --standalone

# ...

$(MD_TARGETS):$(TARGET_DIR)/%.html: $(SOURCE_DIR)/%.md
    mkdir -p $(@D); \
    $(MD) --to html5 $< --output $@; \
    sed -i '' -e '/href="./s/\.md/\.html/g' $@

当我在本地计算机上运行此程序时,一切正常。

当我在Docker中运行相同代码时,出现以下错误:

mkdir -p /project/docs; \
pandoc --from markdown --standalone --to html5 /project/source/changelog.md --output /project/docs/changelog.html; \
sed -i '' -e '/href="./s/\.md/\.html/g' /project/docs/changelog.html
sed: can't read : No such file or directory
makefile:85: recipe for target '/project/docs/changelog.html' failed
make: *** [/project/docs/changelog.html] Error 2

随后调用make会给出相同的错误,但带有另一个文件:

sed: can't read : No such file or directory
makefile:85: recipe for target '/project/docs/todo.html' failed

很显然,请比HTML更早尝试sed。 但是我使用make的多行语法; \,以避免使用subshel​​l。 我也尝试了&& \,但它们都不起作用。我该怎么办?

1 个答案:

答案 0 :(得分:1)

不幸的是,您的“显而易见的”结论误导了您。显然,在不完成HTML的情况下进行sed尝试 :)根本不是问题所在。仔细检查您的错误消息:

sed: can't read : No such file or directory

注意can't read :;应该在那里有一个文件名。它应该说类似can't read foobar:。显然sed正在尝试读取一个名称为空字符串的文件。这是您正在运行的行:

sed -i '' -e '/href="./s/\.md/\.html/g' /project/docs/changelog.html

这里的罪魁祸首是-i的空字符串参数。 sed手册页将-i选项描述为:

   -i[SUFFIX], --in-place[=SUFFIX]

          edit files in place (makes backup if SUFFIX supplied)

请注意(a) SUFFIX 是可选的,以及(b)参数与其选项之间没有空格。在您的示例中,您添加了一个空格,这使sed认为未提供 SUFFIX ,并将下一个参数('')视为要操作的文件名。

我不确定从命令行运行它时为何起作用:我必须假设您的命令行版本不包含空字符串,否则它在{{1之间没有空格}}和-i

使用以下其中一项:

''

sed -i'' -e '/href="./s/\.md/\.html/g' $@