envsubst: команда не найдена в Mac OS X 10.8


92

Когда я пытаюсь запустить сценарий, содержащий команду envsubst, я получаю эту ошибку. Глядя в Интернет, это кажется стандартной командой bash, поэтому я не уверен, что установить, чтобы заставить ее работать.


2
envsubstвходит в gettextкомплект. вы можете компилировать самостоятельно. см. stackoverflow.com/questions/14940383/…
ymonad

Хотите добавить это в качестве ответа, чтобы я мог его принять?
Эндрю

Я разместил это как ответ.
ymonad

Ответы:


131

Изменить: ответ @cobberboy более правильный. проголосовать за него.

brew install gettext
brew link --force gettext 

Вот мой старый ответ:

envsubstвходит в gettextкомплект.

Поэтому вы можете скомпилировать его самостоятельно, используя стандартные инструменты сборки, такие как makeили using homebrew.

Однако при установке gettextв MacOS проблем не возникает. Подробнее см. Следующий URL: Как установить gettext на MacOS X


8
Хотя envsubstэто часть gettext (установленная homebrew), по умолчанию он не связан. Я полагаю, это потому, что gettext - это формула только для кеги. Вы можете сказать Homebrew связать бочонок, но это может иметь непредвиденные побочные эффекты. Менее навязчивый подход - настроить псевдоним, добавив его alias envsubst='/usr/local/Cellar/gettext/0.19.6/bin/envsubst'к вашему .profile(или аналогичному). Конечно, у вас может быть установлена ​​другая версия gettext. Узнать об этом можно, запустив brew info gettext.
trkoch

2
@trkoch Вы, вероятно, захотите использовать псевдоним, /usr/local/opt/gettext/bin/envsubstкоторый выживает после обновлений
Кристоф Хеслер,

1
Хотя это принятый ответ, прокрутите вниз до ответа @cobberboy, так как также часто бывает, что вам нужно принудительно установить ссылку.
Big Money

Я задавался вопросом, почему я внезапно получил больше голосов. Спасибо за щедрость @ymonad
cobberboy

1
Связывание /usr/local/Cellar/gettext/0.19.8.1 ... Создано 194 символических ссылки ... wtf 194 символических ссылки?
Alexander Mills

235
brew install gettext
brew link --force gettext 

Это включит envsubst в OS X и заставит его правильно связываться. Требуется установка homebrew.


1
Linking /usr/local/Cellar/gettext/0.19.8.1... 194 symlinks created... wtf 194 символических ссылок?
Alexander Mills

@AlexanderMills да, gettextвключает в себя чертовски много всего; это кажется излишним просто для envsubstустановки, но это самый быстрый и простой способ.
cobberboy 05

похоже, что они создают символическую ссылку на каждый файл, а не просто на папку
Александр Миллс

17

Чтобы устранить потенциальную путаницу:

  • envsubstявляется внешним исполняемым файлом и, следовательно, не является частью Bash ; внешние исполняемые файлы зависят от платформы , как с точки зрения того, какие из них доступны, так и с точки зрения их конкретного поведения и конкретных параметров, которые они поддерживают (хотя, надеюсь, существует общее подмножество, основанное на спецификациях POSIX)
  • Непосредственно встроенные команды bashназываются встроенными , и только они могут присутствовать на всех платформах .

Чтобы проверить, является ли данная команда встроенной , используйте

type <cmdName>

В данном случае type envsubstвозвращается работа на macOS 10.13 -bash: type: envsubst: not found, из которой вы можете сделать следующие выводы:

  • envsubst НЕ является встроенным
  • envsubstотсутствует в вашей системе $PATH(и, следовательно, скорее всего, отсутствует в вашей системе)

(Напротив, выполнение той же команды on, например, возвращается система Ubuntu 12.04 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будет расширяться оболочками ссылки переменной тоже - а также встроенные команды замена , которая является то , что делает использование evalв проблеме безопасности.

Мне нравится идея, eval echoпотому что я доверяю источнику, но это не то же самое .. envsubst < .env.exampleне может быть простоeval echo < .env.example
iRaS

1

Я использую это сейчас в моем сценарии bash, который требует envsubst:

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

1

Если вы не хотите утруждать себя установкой homebrew и gettext, подойдет однострочный исполняемый файл Perl:

#!/usr/bin/perl -p
$_ =~ s/\Q${$1||$2}/$ENV{$1?$2:$4}/ while $_ =~ /(\$\{([^}]+)})|(\$(\w+))/g;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.