Настройка PATH против экспорта PATH в ~/.bash_profile

Настройка PATH против экспорта PATH в ~/.bash_profile

В чем разница и что лучше использовать при настройке профиля 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) В чем преимущество использования exportPATH по сравнению с его явной установкой?
  • 2) Есть ли какая-либо функциональная разница между версией 1 и версией 2 при применении?
  • 3) Какой из них мне следует использовать и почему?

решение1

Чтобы ответить конкретно на ваши вопросы:

  1. export делаетустановите $PATHявно.

  2. Нет. exportустанавливает среду для дочерних процессов, но $PATHуже установлена ​​для текущей среды. Так, во втором примере, когда команда считывается - идо exportвыполняется - текущее значение среды $PATHрасширяется до $PATHслова.

  3. Вы должны использовать то, что вам необходимо и/или удобно. Ни то, ни другое не имеет функциональной разницы, так что это в первую очередь вопрос стиля.

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

Связанный контент