В чем разница и что лучше использовать при настройке профиля bash? Документация по export
команде скудна, так как это встроенный cmd.
Выдержка из версии 1 моего ~/.bash_profile:
#PATH
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$HOME/bin
#add Homebrew’s sbin to PATH
export PATH=/usr/local/sbin:$PATH
Вывод из:echo $PATH
/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/njboot/bin
Выдержка из версии 2:
#PATH
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$HOME/bin
#add Homebrew’s sbin to PATH
export PATH=/usr/local/sbin:$PATH
Вывод echo $PATH
такой же, как и в версии 1. env
тоже такой же.
Так:
- 1) В чем преимущество использования
export
PATH по сравнению с его явной установкой? - 2) Есть ли какая-либо функциональная разница между версией 1 и версией 2 при применении?
- 3) Какой из них мне следует использовать и почему?
решение1
Чтобы ответить конкретно на ваши вопросы:
export
делаетустановите$PATH
явно.Нет.
export
устанавливает среду для дочерних процессов, но$PATH
уже установлена для текущей среды. Так, во втором примере, когда команда считывается - идоexport
выполняется - текущее значение среды$PATH
расширяется до$PATH
слова.Вы должны использовать то, что вам необходимо и/или удобно. Ни то, ни другое не имеет функциональной разницы, так что это в первую очередь вопрос стиля.
POSIX определяетexport
встроенныйтак:
Оболочка должна присвоить
export
атрибут переменным, соответствующим указанным именам, что приведет к их нахождению в среде последующих выполняемых команд. Если за именем переменной следует= слово, то значение этой переменной должно быть установлено равнымслово.
Из другого моегоответы:
Между объявлением переменной оболочки и переменной окружения нет большой разницы. Поскольку export — встроенная функция, она объявляет переменную окружения для следующего вызываемого процесса, но если вы ее не вызываете, этот процесс остается оболочкой, и поэтому ваша переменная вычисляется дважды.
Вы можете удалить все экспорты без какого-либо эффекта на экспортируемые переменные, если только вы не используете export
дважды вычислять. Под дважды вычислять я подразумеваю:
var1=var2
export "${var1}=var3"
echo "$var2"
var3
Вместо этого просто используйте:
set -a
...в верхней части скрипта. Все переменные, определенные после этого, будут автоматически exported
- что будет включать переменные, которые вы могли не export
редактировать ранее. В качестве альтернативы вы можете только set -a
для части скрипта и позже set +a
отменить его - это также может работать как функция.
Но подоболочки в любом случае автоматически наследуют значения переменных, поэтому:
var1=value
( echo "$(echo "$var1")" )
value
export
В этом случае разницы нет.
Но если ваш скрипт вызывает другой скрипт или любой другой исполняемый файл, который интерпретирует значения, которые вы export
редактировали, и вы прекращаете export
их использовать, то эти значения больше не будут доступны в их среде. В следующем примере я использую переменную оболочки $PS1
, которая определяет содержимое приглашения интерактивной оболочки, чтобы продемонстрировать, как вариации export
переменных редактировали влияют на дочерние процессы.
export PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
this is another executable
> exit
exit
Но ...
PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
sh-4.3$ exit
exit
Но опять же, если вы явно объявляете переменные среды при вызове процесса...
PS1="$(printf "this is another executable\n > ")"
{
echo exit | PS1=$PS1 sh -i
echo exit | sh -i
}
###OUTPUT###
this is another executable
> exit
exit
sh-4.3$ exit
exit
Любой из ENV
файлов, впервые вызванных оболочкой, такой как .bashrc
или, .profile
установит значения переменных на весь срок службы этой оболочки. Поэтому любые переменные, которые устанавливаются и export
редактируются в этих файлах, сохранят эту export
характеристику и будут export
редактироваться во все дочерние процессы, вызванные этой оболочкой на весь срок службы оболочки или пока они не будут unset
.
Однако примечательно, что встроенная функция несколько bash
расширяется export
и включает -n
опцию, которая позволяет удалять export
атрибут из переменной, не unset
изменяя ее, но это непереносимое поведение.
решение2
Краткий ответ:
https://superuser.com/a/153378/333431
Экспортированные переменные передаются дочерним процессам, неэкспортированные — нет.
Это означает, что вам следует export
указать переменные, если вы собираетесь использовать их в подоболочках.
Вы можете это проверить:
$ TEST="im_not_here"
$ echo $TEST
im_not_here
$ bash -c 'echo $TEST'
<empty output>
$ export TEST2="im_here"
$ echo $TEST2
im_here
$ bash -c 'echo $TEST2'
im_here