makefile: 转义字符 / 扩展变量与用户不同

huangapple go评论55阅读模式
英文:

makefile: escape character / expand variable differs with users

问题

@echo "DUPW $DATA.SUBVOL.FILE*"

英文:

I have a makefile where a rule has below echo in a recipe :

@echo "DUPW $(VAR1).FILE*"

The value of variable VAR1 = DATA.SUBVOL

When running the make (on OSS, a Unix like OS) under user A it echoes it the way I want it :

DUPW $DATA.SUBVOL.FILE*

But when running the same make under user B it echoes :

DUPW \DATA.SUBVOL.FILE*

What causes above different behaviour between the 2 users ?

The diffent behaviour also occurs when I change the recipe as follows :

@echo "DUPW $$$(VAR1).DICT*"

But now user A echoes it incorrect :

DUPW $.SUBVOL.FILE*

and user B echoes it in the way I want it :

DUPW $DATA.SUBVOL.FILE*

答案1

得分: 3

好的,以下是翻译好的内容:

嗯,我对 OSS,类Unix操作系统 不太熟悉,所以我不知道它上面的 make 实现是什么。如果运行 make --version,它是否提供任何有用的信息?我熟悉的 make 实现肯定不会同时产生这两种行为。您确定两个用户都在运行 完全相同的 make 实现吗?

基本上,对于用户 B,make 的行为符合 POSIX 标准。像这样的配方行:

@echo "DUPW $(VAR1).FILE*"

将首先展开 makefile 变量 $(VAR1)(在 POSIX make 中,反斜杠在任何方面都不是特殊的;它们只是像任何其他字符一样的字符),所以如果 VAR1 的值是 DATA.SUBVOL,展开的结果将是:

@echo "DUPW \DATA.SUBVOL.FILE*"

如果要在输出中放入字面的 $,可以通过在 make 中写 $$ 来进行转义。然后,由于这是在双引号值中,还必须从 shell 转义字面 $,它使用 \,所以您将使用:

@echo "DUPW $$$(VAR1).FILE*"

如果在您的 shell 命令中切换到单引号,这样 shell 就不会展开,那么您可以省略反斜杠,可能更容易理解:

@echo 'DUPW $$$(VAR1).FILE*'

我不知道正在使用哪个 make 实现,但是用户 A 观察到的行为是错误的/不符合 make 的 POSIX 标准。

英文:

Well, I'm not familiar with OSS, a Unix like OS so I don't know what make implementation is on it. If you run make --version does it tell you anything useful? There's certainly no make implementation I'm familiar with that will emit both those behaviors. Are you sure that both users are running the exact same make implementation?

Basically, the behavior of make for User B is correct according to the POSIX standard. A recipe line like this:

@echo "DUPW $(VAR1).FILE*"

will first expand the makefile variable $(VAR1) (in POSIX make, backslashes are not special in any way; they're just a character like any other character) and so if VAR1 has the value DATA.SUBVOL the result of expansion will be:

@echo "DUPW \DATA.SUBVOL.FILE*"

If you want to put a literal $ in the output, you escape it from make by writing $$. Then, since this is in a double-quoted value you have to escape the literal $ from the shell as well, which uses \ and so you'd use:

@echo "DUPW $$$(VAR1).FILE*"

It might be simpler to understand if you switch to single quotes instead in your shell command, so the shell won't expand. Then you can forgo the backslash:

@echo 'DUPW $$$(VAR1).FILE*'

I have no idea what implementation of make is being used, but the behavior seen by User A is wrong / is not conforming to the POSIX standard for make.

huangapple
  • 本文由 发表于 2023年4月6日 21:11:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定