envsubst:在Mac OS X 10.8上找不到命令


92

当我尝试运行包含envsubst命令的脚本时,出现此错误。从网上看,这似乎是标准的bash命令,因此我不确定要安装什么才能使其正常工作。


2
envsubst包含在gettext包装中。您可以自己编译。看到stackoverflow.com/questions/14940383/...
ymonad

是否希望将其添加为答案,以便我可以接受?
2014年

我将其发布为答案。
ymonad

Answers:


130

编辑:@cobberboy的答案更正确。支持他。

brew install gettext
brew link --force gettext 

以下是我的旧答案:

envsubst包含在gettext包装中。

因此,您可以使用标准构建工具(例如make或)自行编译homebrew

但是,gettext在MacOS中安装时似乎没有什么问题。有关详细信息,请参见以下URL:如何在MacOS X上安装gettext


8
虽然envsubst是gettext的一部分(由自制软件安装),但默认情况下未链接。我希望这是因为gettext是仅桶式的公式。您可以告诉自制程序链接小桶,但这可能会产生意想不到的副作用。较少干扰的方法是通过添加alias envsubst='/usr/local/Cellar/gettext/0.19.6/bin/envsubst'到您的.profile(或等效名称)中来设置别名。当然,您可能已经安装了另一个版本的gettext。您可以通过运行了解它brew info gettext
trkoch

1
@trkoch您可能想要别名/usr/local/opt/gettext/bin/envsubst,使其在升级后仍然存在
ChristophHösler'Dec 20'17

1
虽然这是可接受的答案,但是请向下滚动到@cobberboy的答案,因为您可能需要强制链接,这也是常见的情况。
Big Money

我想知道为什么我突然得到更多支持。感谢您的慷慨@ymonad
cobberboy

1
链接/usr/local/Cellar/gettext/0.19.8.1 ...创建了194个符号链接... wtf 194个符号链接?
亚历山大·米尔斯

233
brew install gettext
brew link --force gettext 

这将在OS X上启用envsubst,并强制其正确链接。它需要安装自制软件。


1
Linking /usr/local/Cellar/gettext/0.19.8.1... 194 symlinks created... wtf 194符号链接?
亚历山大·米尔斯

@AlexanderMills是的,gettext其中包括很多东西。似乎只是为了envsubst安装而已,不过这是最快,最简单的方法。
cobberboy

似乎他们正在符号链接每个文件,而不仅仅是符号链接文件夹
Alexander Mills

17

为消除潜在的混乱:

  • envsubst外部可执行文件,因此不是Bash的一部分 ; 外部可执行文件是平台相关的,无论是可用的,还是它们的特定行为以及它们所支持的特定选项(尽管,希望有一个基于POSIX规范的公共子集)
  • 直接内置于其中的命令bash称为内置程序,只有它们可以依赖它们存在于所有平台上

测试给定命令是否为内置命令,请使用

type <cmdName>

在当前情况下,type envsubst在macOS 10.13上运行将返回-bash: type: envsubst: not found,您可以从中推断:

  • envsubst 不是内置的
  • envsubst不在您的系统中$PATH(因此可能不在您的系统中)

(相反,在Ubuntu 12.04等系统上的命令上运行相同的命令将返回envsubst is hashed (/usr/bin/envsubst),这告诉您该实用程序存在并且位于该位置。)


临时替代项envsubst是use eval,尽管通常需要注意:eval仅在您控制或信任其内容的字符串上使用:

假设一个sample.txt文件包含带有未扩展变量引用的文本;例如:

cat > sample.txt <<'EOF'
Honey, I'm $USER
and I'm $HOME.
EOF

相当于:

envsubst < sample.txt

是:

eval "echo \"$(sed 's/"/\\"/g' sample.txt)\""

但是,有一个关键的区别

  • envsubst扩展环境变量引用
  • eval将扩大外壳变量引用 -以及嵌入式命令替换,这是利用了eval一个安全问题。

我喜欢这样的想法,eval echo因为我相信消息来源,但事实并非如此.. envsubst < .env.example不能仅仅是eval echo < .env.example
iRaS

1

我现在在需要envsubst的bash脚本中使用它:

if ! which envsubst > /dev/null 2>&1; then
    envsubst() {
        while read line; do
            line=$( echo $line | sed 's/"/\\"/g' )
            eval echo $line
        done
    }
fi

您可以将其用作envsubst命令-当然,它不具有完整功能或其他功能:

envsubst <<<'Honey, I am $HOME.'
envsubst < input > output 2> corrupt

这似乎剥夺了所有开头和结尾的空格
sudo

如前所述,这是功能不完善的解决方法。您可以尝试"在$ line附近添加,但是我还没有尝试过
iRaS

0

如果您不想麻烦安装homebrew和gettext,一个perl perl可以做到:

#!/usr/bin/perl -p
$_ =~ s/\Q${$1||$2}/$ENV{$1?$2:$4}/ while $_ =~ /(\$\{([^}]+)})|(\$(\w+))/g;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.