当我尝试运行包含 envsubst 命令的脚本时,出现此错误。在网上看,这似乎是一个标准的 bash 命令,所以我不确定要安装什么才能让它工作。
brew install gettext
brew link --force gettext
这将在 OS X 上启用 envsubst,并强制其正确链接。它需要安装自制程序。
编辑:@cobberboy 的答案更正确。给他点赞。
brew install gettext
brew link --force gettext
以下是我的旧答案:
envsubst
包含在 gettext
包装中。
因此,您可以使用标准构建工具(例如
make
)或使用homebrew
自行编译它。
不过,在MacOS中安装
gettext
时似乎没有什么问题。
详细信息请参阅以下网址:如何在 MacOS X 上安装 gettext
为了消除潜在的混乱:
envsubst
是一个 external 可执行文件,因此 不是 Bash 的一部分;外部可执行文件是平台相关的,无论是可用的还是它们的特定行为和它们支持的特定选项(尽管希望有一个基于 POSIX 规范的通用子集)bash
中的命令称为 builtins,并且只有 它们 才能出现在 所有 平台上。要测试给定命令是否是内置命令,请使用:[1]
type <cmdName>
在本例中,在 macOS 14 (Sonoma) 上运行
type envsubst
返回 -bash: type: envsubst: not found
,从中您可以推断:
envsubst
不是内置的envsubst
不在您系统的 $PATH
中(因此可能不存在于您的系统中)(相比之下,在 Ubuntu 12.04 系统等上运行相同的 on 命令会返回
envsubst is hashed (/usr/bin/envsubst)
,这会告诉您该实用程序是否存在以及它位于何处。)
envsubst
的临时替代方案是使用 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
将扩展 shell 变量引用 too - 以及 嵌入式 命令替换,这就是使用 eval
带来 安全问题的原因。[1] 如果给定命令 是 内置命令,则会打印一条消息,例如
<command> is a shell builtin
。要以以编程方式测试此条件,请使用类似 type <command> 2>/dev/null | grep -q builtin && echo "IS A BUILTIN"
的内容
我现在在需要 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
如果您不想安装 homebrew 和 gettext,单行 perl 可执行文件就可以了:
#!/usr/bin/perl -p
$_ =~ s/\Q${$1||$2}/$ENV{$1?$2:$4}/ while $_ =~ /(\$\{([^}]+)})|(\$(\w+))/g;
如果你不想安装 homebrew 和 gettext,并且 无法搞懂 Perl ,一个简单的 Python 脚本也能做到这一点:
envsubst() {
python -c 'import os,sys;[sys.stdout.write(os.path.expandvars(l)) for l in sys.stdin]'
}
与
eval
解决方案相比,它的优势在于它仅处理变量替换,不会像 eval
那样执行任意脚本。
$ cat > sample.txt <<'EOF'
Honey, I'm $USER
and I'm $HOME.
Danger: $( echo 'eval can do evil here, but python expandvars rocks' )
EOF
$ envsubst < sample.txt
Honey, I'm mattmc3
and I'm /Users/mattmc3.
Danger: $( echo 'eval can do evil here, but python expandvars rocks' )