带有此处文档重定向的 Makefile 配方
Makefile recipe with a here-document redirection
有谁知道如何在食谱上使用此处文档重定向?
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 的 shell)但它需要更改我的食谱而且我有很多。
Strip 从宏中删除换行符,然后所有内容都写在一行中。
我的最终目标是:proxy := docker run ...
使用 Makefile 中某处的行 .ONESHELL:
会将所有配方行发送到单个 shell 调用,您应该会发现原始 Makefile 可以正常工作。
当 make 看到配方中的多行块时
(即除了最后一行以外,所有行都以 \
结尾),
它将未修改的块传递给 shell。
这通常适用于 bash,
除了这里的文档。
解决此问题的一种方法是去除任何尾随的 \
s,
然后将结果字符串传递给 bash 的 eval
。
您可以在 make 中使用 ${.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
小心引用,尤金。
注意这里的作弊:
我正在删除所有反斜杠,
不仅仅是行尾的那些。
YMMV.
使用 GNU make,您可以结合 multi-line variables with the export
指令使用多行命令,而无需全局打开 .ONESHELL
:
export define script
cat <<'EOF'
here document in multi-line shell snippet
called from the "$@" target
EOF
endef
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'ism。
将这些行放在带有括号的子 shell 中,在每行前面加上 echo。
您需要尾随斜杠和 semi-colon 以及适当的斜杠。
test:
( \
echo echo I Need This ;\
echo echo To Work ;\
echo ls \
) \
| sh
有谁知道如何在食谱上使用此处文档重定向?
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 的 shell)但它需要更改我的食谱而且我有很多。 Strip 从宏中删除换行符,然后所有内容都写在一行中。
我的最终目标是:proxy := docker run ...
使用 Makefile 中某处的行 .ONESHELL:
会将所有配方行发送到单个 shell 调用,您应该会发现原始 Makefile 可以正常工作。
当 make 看到配方中的多行块时
(即除了最后一行以外,所有行都以 \
结尾),
它将未修改的块传递给 shell。
这通常适用于 bash,
除了这里的文档。
解决此问题的一种方法是去除任何尾随的 \
s,
然后将结果字符串传递给 bash 的 eval
。
您可以在 make 中使用 ${.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
小心引用,尤金。 注意这里的作弊: 我正在删除所有反斜杠, 不仅仅是行尾的那些。 YMMV.
使用 GNU make,您可以结合 multi-line variables with the export
指令使用多行命令,而无需全局打开 .ONESHELL
:
export define script
cat <<'EOF'
here document in multi-line shell snippet
called from the "$@" target
EOF
endef
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'ism。 将这些行放在带有括号的子 shell 中,在每行前面加上 echo。 您需要尾随斜杠和 semi-colon 以及适当的斜杠。
test:
( \
echo echo I Need This ;\
echo echo To Work ;\
echo ls \
) \
| sh