Bash gmake$(shell)函数中的转义
我有一个环境变量GITHUB_REFS,我想对它执行一些bashism操作,并从GNU makefile的另一个变量GITHUB_分支中捕获结果。我天真的做法是这样的:Bash gmake$(shell)函数中的转义,bash,makefile,environment-variables,gnu-make,Bash,Makefile,Environment Variables,Gnu Make,我有一个环境变量GITHUB_REFS,我想对它执行一些bashism操作,并从GNU makefile的另一个变量GITHUB_分支中捕获结果。我天真的做法是这样的: SHELL:=/bin/bash GITHUB_BRANCH:=$(shell echo "${GITHUB_REF#refs/heads/}") HASH := \# foo := $(shell echo "${GITHUB_REF$(HASH)refs/heads/}") 如果我单独运行Bashim,它可以正常工作,
SHELL:=/bin/bash
GITHUB_BRANCH:=$(shell echo "${GITHUB_REF#refs/heads/}")
HASH := \#
foo := $(shell echo "${GITHUB_REF$(HASH)refs/heads/}")
如果我单独运行Bashim,它可以正常工作,但是当运行上面的makefile时,它会失败:
Makefile:2: *** unterminated call to function 'shell': missing ')'. Stop.
我试图逃离as\,因为它是一个貌似有理的罪魁祸首,事实上,然后Makefile可以工作,而bashism不能。双重转义会再次出现相同的错误
那么我如何才能实现这一点呢?可以使用\来转义,但您也忘记了转义$
此Makefile可以工作:
SHELL:=/bin/bash
foo := $(shell echo "$${SHELL\#/bin/}")
all:
echo $(foo)
您还需要将美元符号加倍才能将其传递到shell
GITHUB_BRANCH:=$(shell echo "$${GITHUB_REF\#refs/heads/}")
值得一提的是,这个简单的参数扩展可以移植到任何合理的现代sh,因此根本不是Bash独有的特性
当然,make完全能够执行相同的替换,而无需调用外部进程
GITHUB_BRANCH := $(patsubst refs/heads/%,%,${GITHUB_REF})
需要注意的是,这是一个bug,将在即将发布的GNU make版本中修复。如果希望在修复错误之前/之后使makefile可移植,则应将其隐藏在如下变量中:
SHELL:=/bin/bash
GITHUB_BRANCH:=$(shell echo "${GITHUB_REF#refs/heads/}")
HASH := \#
foo := $(shell echo "${GITHUB_REF$(HASH)refs/heads/}")
这将适用于所有版本的GNU make。您是否尝试过定义一个只包含以下内容的make变量?这是一种常用于空间之类的技术。此外,您忘了转义$-应该是${GITHUB\u REFrefs/heads/}您不应该像这样关闭括号吗$shell echo${GITHUB_REF}refs/heads/@Tim No,OP正在尝试使用shell的功能。然后我建议同时转义$,并且通过使用$$和\FWIW,原始的Bourne shell不支持这种扩展语法。看见在ksh88年首次引入IIRC。然而,您很难找到任何工作的UNIX系统,其中/bin/sh实际上是BourneShell,而不是dash、bash等。