Как я могу получить вывод переменной оболочки для использования в моей capistrano задаче

Я использую capistrano для развертывания приложения Ruby on Rails. Я ранее использовал Centos. В преобразовании моей задачи, которая будет использоваться с Ubuntu, у меня есть задача, которую я использовал для Centos, был:

 capture("env | grep ENV_VAR").split("=").last

Это получило бы вывод той переменной в удаленной системе, которая будет использоваться в моем коде. Однако этот код, кажется, не работает с Ubuntu. Кто-либо может сказать мне, как я могу получить вывод переменной с помощью capistrano и человечности?

Я попробовал

capture("echo $ENV_VAR")

Но это распечатывает пустую строку. Я предполагаю, что проблемой является reated к "$", но я не уверен.

Спасибо за любую справку заранее.

2
задан 28 April 2015 в 21:16

2 ответа

Я наконец споткнулся через этот ответ. Способ сделать это должно загрузить оболочку удара и передать команду ему.

capture("/bin/sh -c 'echo $ENV_VAR'")
0
ответ дан 2 December 2019 в 02:57

Использовать printenv вместо этого, который не требует оболочки:

capture('printenv ENV_VAR')

Замена ENV_VAR с названием переменной среды Вы хотите. Не предварительно ожидать $.

Хотя printenv не POSIX, системы GNU/Linux как Debian, Ubuntu, Fedora, и CentOS поддерживают его, потому что GNU, который Coreutils обеспечивает ему, и это работает над многими другой *, отклоняют системы, как FreeBSD. Причина необходимо использовать printenv вместо env это printenv ENV_VAR производит значение ENV_VAR, в то время как env ENV_VAR попытки выполнить названную команду ENV_VAR, который не является тем, что Вы хотите.


Остальная часть этого сообщения покрывает другие методы, их ограничения, и как они могут быть улучшены. Это - дополнительное чтение с тех пор printenv просто и решает проблему полностью.

Ваш исходный метод, capture("env | grep ENV_VAR").split("=").last, не должен использоваться даже в системе, где это, действительно кажется, работает, потому что это ненадежно. Это greps для имени переменной везде в VAR=val строка, и таким образом возвратит результаты для переменных, имена которых - или даже оценивает - содержат название желаемой переменной. Используя ^ENV_VAR= вместо ENV_VAR решает эту проблему путем соответствия имени только, когда это появляется в начале строки (^) и требование a = символ для появления прямо после него. Однако для значения переменной среды возможно содержать = символ, и так как Вы звоните split и last, Вы на самом деле получаете самую длинную запаздывающую подстроку значения, которое содержит нет =. Даже при фиксации этого метод все еще напрасно сложен, когда все, в чем Вы нуждаетесь, printenv.

Решение Вы нашли, capture("/bin/sh -c 'echo $ENV_VAR'"), будет работать большую часть времени, но возвратит неправильное значение, когда переменная (a) содержит пробел кроме символов одиночного пробела, окруженных непробелом, или (b) содержит globbing символы как *, ?, и [ если они, оказывается, соответствуют каким-либо именам файлов. Проблема состоит в том, что, в оболочке управляют echo $ENV_VAR, расширение параметра $ENV_VAR не заключается в кавычки, таким образом, разделение слова и globbing выполняются. echo повторно вставляет пробел, но не всегда таким же образом: echo foo bar печать foo bar, но так делает echo foo bar. Эта проблема может быть решена путем размещения "" кавычки вокруг расширения, хотя необходимо будет или выйти из них так интерпретатор Ruby, не берут их в качестве окончания "- заключенная в кавычки строка и запуск нового, или Вы можете '- заключите строку Ruby в кавычки и выйдите из любого внутреннего ' персонажи.

Вы также получаете неправильный результат в менее общей ситуации что значение ENV_VAR начинается с опции это echo поддержки. Отличающийся echo реализации поддерживают различные варианты; -n и -e распространены. Большинство оболочек имеет echo как встроенное и может поддерживать различные варианты от других оболочек и от /bin/echo. Это должно сказать это echo не является очень портативным. Разумно для осмотра переменных среды в интерактивном режиме, когда Вы, вероятно, поймете, происходит ли что-то нечетное, но меньше для сценариев. echoгоре мобильности усилено как /bin/sh не всегда bash. В Ubuntu это dash. При помощи этого можно избежать printf '%s\n' или printf "%s\n" вместо echo (или, в Вашем случае, printf %s мог бы быть достаточным).

Таким образом Ваше решение может быть улучшено до capture('/bin/sh -c \'printf "%s\n" "$ENV_VAR"\''). Это может выглядеть неправильным опытным сценаристам оболочки, которые не знают Ruby; обратите внимание, что Ruby, в отличие от Bash и других оболочек стиля Границы, рассматривает \' как литерал ' внутри a ''- заключенная в кавычки строка. Даже при том, что это корректно, Ваши коллеги должны будут посмотреть на него дважды для удовлетворения этого, даже если они являются опытными и в Ruby и в сценариях оболочки. capture('printenv ENV_VAR') более просто.

3
ответ дан 2 December 2019 в 02:57

Другие вопросы по тегам:

Похожие вопросы: