【问题标题】:Why is "$_" not expanded as expected by GNU make shell function?为什么“$_”没有按 GNU make shell 函数的预期扩展?
【发布时间】:2014-12-23 20:42:17
【问题描述】:

考虑命令make --eval '$(error $(shell echo foo && echo $$_))'(或3.82 之前的make 版本的等效makefile,其中似乎添加了eval 选项)。我希望这会输出“foo foo”,这就是 Cygwin 下的 gmake 3.82.90 发生的情况。但是 Debian 下的 gmake 3.81 和 4.0 输出的是“foo /usr/bin/make”。

有人明白为什么会这样吗?

当然,在真正的 makefile 中,shell 命令的第一部分比简单的回显要复杂一些,其想法是仅在命令成功时才输出其参数,否则将其留空以指示失败。这似乎比我的其他替代方案更优雅,并且在初始测试中工作(在 Cygwin 下),但显然我现在必须做其他事情......

【问题讨论】:

  • 我在 debian 包中使用 GNU Make 4.0 看到了相同的行为,但我没有看到在 CentOS 5 上手动构建的 GNU Make 4.0。我从 foo foo CentOS的自建版本。
  • 感谢测试!这让事情变得更加……有趣。我检查了Debian patches,但那里似乎没有任何相关内容。确实是越来越好奇了。
  • 在 Arch Linux 上使用 pacman 安装的 GNU Make 4.1 也会打印出 foo foo

标签: shell gnu-make


【解决方案1】:

这是一个 shell 问题,而不是 make 问题。不知道为什么我最初没有看到。

Debian

$ /bin/bash --version
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
$ /bin/bash -c 'echo foo && echo $_'
foo
foo
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Nov  8 08:49 /bin/sh -> dash
$ /bin/sh -c 'echo foo && echo $_'
foo
/bin/sh
$ /bin/dash -c 'echo foo && echo $_'
foo
/bin/dash

CentOS

$ /bin/bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
$ /bin/bash -c 'echo foo && echo $_'
foo
foo
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Sep 29 10:39 /bin/sh -> bash
$ /bin/sh -c 'echo foo && echo $_'
foo
foo

所以这里的问题是$_ 何时获得它的非启动值。似乎 dash 和 bash(在较新版本的 bash 中处于 sh 兼容模式)同意它不应该被设置。

我不知道规范是怎么说的。

更新:一些快速搜索表明$_ 在许多方面都是一种 bash 主义(尽管启动值似乎更广泛地可移植)。 $_ 也恰好是一个令人难以置信的混淆变量,因为它可以根据上下文做许多不同的事情。

【讨论】:

  • 我应该说我最初确实认为这是一个 shell 问题,但在提出问题时为了简洁起见决定省略它,因为在我看来它不是:首先,我使用几乎相同Cygwin 和 Debian (4.3) 下的 zsh。其次,bash 确实为我输出了foo\nfoo。但是,这很关键,/bin/dash 没有,这确实解释了 make 结果总是使用 /bin/sh(在 Debian 下符号链接到破折号)而不是 SHELL 值。所以...最后你是绝对正确的,谢谢!
  • 您可以手动设置SHELL,但它不会使用现有的环境变量。
猜你喜欢
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多