docker - Makefile 多行命令在 Docker 中无法正常工作
问题描述
我正在尝试从 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
sed
显然,在 HTML 完成之前,make 会以某种方式尝试。但是我使用 make 的多行语法; \
以避免使用 subshell。我也尝试过&& \
,但它们都不起作用。我应该怎么办?
解决方案
不幸的是,您被您的“明显”结论误导了显然,在 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并将下一个参数 ( ''
) 视为要操作的文件名。
我不确定为什么从命令行运行它时它会起作用:我必须假设您的命令行版本不包含空字符串,否则它不包含在-i
和''
.
使用以下之一:
sed -i'' -e '/href="./s/\.md/\.html/g' $@
或者
sed --in-place= -e '/href="./s/\.md/\.html/g' $@
推荐阅读
- swift - 通过告诉调用哪个函数来快速初始化类
- reactjs - 未捕获的错误:在生产中只允许一个 babel-polyfill 实例出现错误
- ios - 使用 ARKit 拍摄高质量照片
- r - 请解释我们如何将因子变量转换为 R 中的数字
- python - 查找使用 OpenCV 检测到的线的角度
- r - R Markdown 中的 Zotero 引用
- matlab - Matlab如何对IV进行排序并将其映射到唯一的H值
- embedded-linux - bitbake 不生成 zImage 文件
- apache-kafka - 我应该在哪里写我的 Kafka 适配器/连接器来从主题中读取数据?
- apache - 缺少 mysqli 扩展。请检查您的 PHP 配置,即使文件在定义的路径中可用