具有here-document重定向的Makefile配方

问题描述 投票:6回答:4

有谁知道如何在食谱上使用here-document重定向?

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 ...

bash shell makefile gnu-make heredoc
4个回答
6
投票

在Makefile中的某处使用行.ONESHELL:会将所有配方行发送到单个shell调用,您应该会发现原始Makefile按预期工作。


3
投票

当make在配方中看到一个多行块时(即,一行以\结尾,除了最后一行),它将未修改的块传递给shell。这通常适用于bash,除了这里的文档。

解决这个问题的一种方法是去除任何尾随的\s,然后将结果字符串传递给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

小心引用,尤金。请注意这里的作弊:我正在删除所有反斜杠,而不仅仅是行末端的反斜杠。因人而异。


1
投票

使用GNU make,您可以将multi-line variablesexport指令结合使用多行命令,而无需全局启用.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

0
投票

不是这里的文档,但这可能是一个有用的解决方法。它不需要任何GNU Make'isms。将行放在带有parens的子shell中,在每行前面加上echo。在适当的情况下,你需要拖尾晃动和分叉和晃动。

test:
( \
    echo echo I Need This ;\
    echo echo To Work ;\
    echo ls \
) \
| sh
© www.soinside.com 2019 - 2024. All rights reserved.