>有谁知道如何在食谱上使用此处文档重定向?
test:
sh <<EOF
echo I Need This
echo To Work
ls
EOF
我找不到任何尝试通常的反斜杠方法的解决方案(该方法基本上以单行命令结尾)。
理由:
我有一组多行配方,我想通过另一个命令(例如,sh,docker)代理。
onelinerecipe := echo l1
define twolinerecipe :=
echo l1
echo l2
endef
define threelinerecipe :=
echo l1
echo l2
echo l3
endef
# sh as proxy command and proof of concept
proxy := sh
test1:
$(proxy) <<EOF
$(onelinerecipe)
EOF
test2:
$(proxy) <<EOF
$(twolinerecipe)
EOF
test3:
$(proxy) <<EOF
$(threelinerecipe)
EOF
我想避免的解决方案:将多行宏转换为单行。
define threelinerecipe :=
echo l1;
echo l2;
echo l3
endef
test3:
$(proxy) <<< "$(strip $(threelinerecipe))"
这有效(我使用 gmake 4.0 和 bash 作为 make 的外壳),但它需要改变我的食谱,我有很多。Strip 从宏中删除换行符,然后将所有内容都写入一行中。
我的最终目标是:proxy := docker run ...
中的某处使用.ONESHELL:
行会将所有配方行发送到单个 shell 调用,您应该会发现原始 Makefile 按预期工作。
当 make 在配方中看到多行块时(即,除了最后一条以外,所有以结尾的行块),它将未修改的块传递给外壳。这通常适用于 bash,除了这里文档。
解决此问题的一种方法是去除任何尾随,然后将生成的字符串传递给 Bash 的
eval
。您可以通过玩${.SHELLFLAGS}
和${SHELL}
来做到这一点。如果您只希望它针对几个目标启动,则可以以特定于目标的形式使用这两个
.PHONY: heredoc
heredoc: .SHELLFLAGS = -c eval
heredoc: SHELL = bash -c 'eval "$${@//\\/}"'
heredoc:
@echo First
@cat <<-there
here line1
here anotherline
there
@echo Last
给
$ make
First
here line1
here anotherline
Last
小心引用,尤金。请注意这里的作弊:我正在删除所有反斜杠,不仅仅是线末端的那些。扬子晚报.
GNU make,您可以将多行变量与 export
指令结合使用以使用多行命令,而不必全局打开.ONESHELL
:
define script
cat <<'EOF'
here document in multi-line shell snippet
called from the "$@" target
EOF
endef
export script
run:; @ eval "$$script"
会给
here document in multi-line shell snippet
called from the "run" target
您还可以将其与 value
函数结合使用,以防止其值被 make 扩展:
define _script
cat <<EOF
SHELL var expanded by the shell to $SHELL, pid is $$
EOF
endef
export script = $(value _script)
run:; @ eval "$$script"
会给
SHELL var expanded by the shell to /bin/sh, pid is 12712
不是这里的文档,但这可能是一个有用的解决方法。而且它不需要任何GNU Make'isms。将线条放入带有 paren 的子壳中,在每行前面加上回声。在适当的情况下,您需要尾随晃动以及分号和晃动。
test:
(
echo echo I Need This ;
echo echo To Work ;
echo ls
)
| sh