【问题标题】:Escaping # in gmake $(shell) function在 gmake $(shell) 函数中转义 #
【发布时间】:2020-01-08 09:14:30
【问题描述】:

我有一个环境变量 GITHUB_REFS,我想对其执行一些 bashism 并从 GNU makefile 中将结果捕获到另一个变量 GITHUB_BRANCH 中。我的幼稚做法是这样的:

SHELL:=/bin/bash
GITHUB_BRANCH:=$(shell echo "${GITHUB_REF#refs/heads/}")

如果我自己运行 bashism,它可以正常工作,但是在运行上面的 makefile 时会失败:

Makefile:2: *** unterminated call to function 'shell': missing ')'.  Stop.

我尝试将# 转义为\#,因为它可能是罪魁祸首,然后Makefile 确实有效,但是bashism 无效。双重转义它再次给出相同的错误。

那么我该如何解决呢?

【问题讨论】:

  • 您是否尝试过定义一个只包含# 的Make 变量?这是一种经常用于空间等的技术。此外,您忘记转义 $ - 应该是 $${GITHUB_REF#refs/heads/}
  • 不应该先把括号合上,像这样吗? $(shell echo "${GITHUB_REF}#refs/heads/")
  • @Tim 不,OP 正在尝试使用 shell 的 parameter expansion 功能。
  • 那么我建议使用$$\# 转义$#

标签: bash makefile environment-variables gnu-make


【解决方案1】:

您还需要将美元符号加倍才能将其传递给 shell。

GITHUB_BRANCH:=$(shell echo "$${GITHUB_REF\#refs/heads/}")

不管怎样,这个简单的参数扩展可以移植到任何相当现代的sh,所以根本不是 Bash 独有的功能。

当然,make 完全能够执行相同的替换,而无需调用外部进程。

GITHUB_BRANCH := $(patsubst refs/heads/%,%,${GITHUB_REF})

【讨论】:

【解决方案2】:

# 可以使用\ 进行转义,但您也忘记了对$ 进行转义。

这个 Makefile 有效:

SHELL:=/bin/bash

foo := $(shell echo "$${SHELL\#/bin/}")

all:
    echo $(foo)

【讨论】:

    【解决方案3】:

    请注意,这(需要转义 #)是一个错误,将在即将发布的 GNU make 版本中修复。如果你想让你的makefile在bug修复之前/之后可以移植,你应该把它隐藏在一个像这样的变量中:

    HASH := \#
    
    foo := $(shell echo "${GITHUB_REF$(HASH)refs/heads/}")
    

    这适用于所有版本的 GNU make。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2012-01-19
      • 2012-03-10
      相关资源
      最近更新 更多