LINUX.ORG.RU
ФорумAdmin

export PATH

 ,


0

3

Всем привет

Вопрос касается export. Export превращает локальную переменную в переменную окружения. В bashrc есть такая строчка -

PATH=$PATH:/foo:/bar

export PATH

нахрен здесь export? ведь PATH и так переменная окружения. Я раньше думал, что для того, чтобы и значение этой переменной экспортнулось, но сегодня заметил, что и без export дочерняя сессия получает это значение - допустим, если написать

LANG=ru_RU.UTF-8

bash

echo $LANG

то значение будет ru_RU.UTF-8 без всякого экспорта.

То есть, как я понял, export просто превращает локальную переменную в переменную окружения и смысла его запускать для уже существующих переменных окружения нет, то есть бессмысленно писать export PATH, но зачем-то он везде прописан? ладно, предположим, что PATH до этого не задана но ведь сама переменная PATH=$PATH:/foo:/bar намекает, что используй существующую переменную PATH.



Последнее исправление: Datt_ (всего исправлений: 2)

Ну старо же как мир.

$ echo $var

$ cat just_var
VAR=123
$ source just_var
$ echo $var

$ cat export_var
export var=123
$ source export_var
$ echo $var
123
shell-script ★★★★★
()
Ответ на: комментарий от shell-script

Почему никто не читает, что речь идет о заданных переменных среды,которые уже были экспортнуты, а не локальных?

В файле ~/.bashrc указана переменная PATH=$PATH:/home/user/bin…., что обыденная ситуация, чтобы пользователь мог указывать свои директории для запуска программ. Но после этой переменной стоит export PATH.  export нужен для локальных переменных, а вот экспортить уже переменные среды бессмысленно. Но почему-то эта надпись есть.

Кто-то на форуме указал, что это нужно для превентивной защиты от дураков, мол если вдруг не задана переменная окружения PATH, то отсюда она задастся. Но если не задана переменная PATH, то в файле ~/.bashrc она примет значение PATH=:/home/user/bin, а каким образом это защитит от дураков мне так никто и не ответил.

Кто-то сказал, что на Солярисе нужно вручную указывать export, если меняется переменная среды, но речь вовсе не про Солярис.

Кто-то ударился в объяснения разницы между ~/.bash_profile и ~/.bashrc, но я как-бы не об этом спрашивал.

Datt_
() автор топика
Ответ на: комментарий от Datt_

Переменная PATH не простро экспортированная. Она читается шеллом отдельно(man bash). И тут не важно, есть export или нет.

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
$ PATH=$BLABLABLA:/bin
$ echo $PATH
:/bin
$ ls
Downloads  desktop  downloads  perl5  random
$ which ls
/bin/ls
$ PATH=$BLABLABLA:/binasd
$ ls
-bash: ls: command not found
$ which ls
-bash: which: command not found
$ echo $PATH
:/binasd

shell-script ★★★★★
()
Последнее исправление: shell-script (всего исправлений: 2)
Ответ на: комментарий от shell-script

… можно просто ответить на мой вопрос - зачем нужно было в ~/.bashrc писать export PATH? Хоть кто-нибудь..

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

Неужели я неясно поставил вопрос? Повторю на всякий случай. Зачем в ~/.bashrc надпись export PATH ?

Мне не нужно объяснять ничего другого. Просто ответ на этот вопрос.

Datt_
() автор топика

Разумеется:

PATH=$PATH:/foo:/bar

недостаточно пароноидально. Нужно как-то так:

PATH=~/src/utils/bin:~/bin${PATH:+:${PATH}}

Откройте терминал и сделайте команды:

unset PATH
/bin/bash --norc
echo $SHLVL $PATH
PATH=$PATH:aaa
/bin/bash --norc
echo $SHLVL $PATH

В выводе от последней команды осталось «aaa»? Только, если у вас bash по другому пути, то пишите его, вместо /bin/bash.

Я не знаю, какой у вас bash, может патченный. Обычный bash, запускаемый без переменной среды PATH создаст bash-переменную PATH и определит её в значение по умолчанию. Но, так как переменной среды PATH нет, то bash-переменная не будет экспортируемой, то есть не будет определять переменную среды для дочерних процессов.

mky ★★★★★
()
Ответ на: комментарий от mky

Речь идет об обычном десктопном Centos8, где в /etc/profile есть надпись export PATH. То есть PATH уже задан как переменная среды еще до того, как прочесть ~/.bashrc.

Datt_
() автор топика

Тут уже 10 раз написали, что это для совместимости с самым общим posix shell. И заметь, export идет отдельной строкой, а не export VAR=... - это тоже для совместимости. Потому что profile будет\должен быть загружен в любой запущенный тобой шелл, не только баш.

И я все еще сомневаюсь, что PATH штатно устанавливается в bashrc, а не profile. Это было бы криво, http://superuser.com/a/789465

zendrz ★★
()

Export превращает локальную переменную в переменную окружения.

Нет.

В вашей терминологии «локальная переменная» тоже является переменной окружения, но текущего процесса. Она невидима дочерним процессам.

export делает переменную окружения текущего процесса видимой дочерним процессам.

Дочерний процесс не может изменить переменную окружения родительского процесса.

Точка.

akk ★★★★★
()
Ответ на: комментарий от akk

Вы какую-то фигню написали.

export делает переменную окружения текущего процесса видимой дочерним процессам.

test1 = локальная переменная. Но export делает её видимой дочерним процессам. А значит export делает локальную переменную видимой дочерним процессам

Дочерний процесс не может изменить переменную окружения родительского процесса.

я где-то утверждал обратное?

Datt_
() автор топика
Ответ на: комментарий от zendrz

Пожалуйста, взгляните на скриншот: https://imgur.com/KC7xdxI

Вкратце поясню.

  1. Стандартный Centos8. В файле /etc/skel/.bashrc, который штатно копируется в домашнюю директорию пользователей при их создании, есть PATH и export PATH. Если вам кажется, что я это подделал, можете поискать в интернете или даже сами развернуть виртуалку и проверить.

  2. Я запустил штатную /usr/bin/sh. Это "When Bash, mksh and zsh are invoked with the sh name, they automatically become more POSIX compliant. ", установленный в Centos 8. Сначала я вывел текущий PATH. Затем изменил его ( PATH=/usr/bin, /usr/sbin/ ). Не сделал экспорт, но запустил дочерний sh. В нём я проверил, получила ли дочерняя сессия изменённое значение переменной PATH без экспорта - и да, там я увидел измененное. То есть для встроенного sh, который стал дочерним процессом, от самого же sh всё нормально передалось и без повторного export, то есть export PATH не нужен был. Не значит ли это, что он либо не posix совместим, либо posix shell тоже так умеет?

Если вы говорите для совместимости, то приведите пример, чтобы я понял, где этот export в ~/.bashrc прям необходим и где что сломается без него?

Datt_
() автор топика
Последнее исправление: Datt_ (всего исправлений: 5)
Ответ на: комментарий от Datt_

Я запустил штатную /usr/bin/sh.

А там скорее всего ссылка символическая на bash || dash || ash || что-то еще, так что ты запустил далеко не каноничный sh.

давай ка ты нам покажешь ls -lha /usr/bin/sh для начала.

завязывай свой тупняк, тебе уже прекрасно написали для чего нужен export, а ты все предлагаешь закладываться на поведение какого-то конкретного дистрибутива в надежде что такое поведение везде.

anonymous
()
Ответ на: комментарий от anonymous

В комменте выше я сказал, что sh - это When Bash, mksh and zsh are invoked with the sh name, they automatically become more POSIX compliant. ", если вы не поняли, там bash.

Тупняк у вас, я спрашиваю, почему так написано, это не имеет значения, не важно, написано это в одном дистре или во всех. Да хоть в одном центос, можно просто ответ на мой вопрос, зачем?

Если речь о совместимости, пришлите скриншот, где вы не сделали export и все поломалось. А потом объясните, почему это нужно в Centos, ведь дефолтный шелл там баш, а на zsh это тоже работает как на bash

Datt_
() автор топика
Ответ на: комментарий от Datt_

Такая никак, т.к. это уже даже не дурак, подобным ты еще и весь существующий PATH затираешь, но это ты понять вполне способен.

Не передергивай это защита от дурака, на случай когда по какой-то причине PATH не была вообще проэкспортирована в окружение, и в данном случае даже с таким PATH тот софт который закладывается на этот путь в PATH будет исправно работать. Как я написал ранее это конечно не спасет другой софт для которого ты затер пути которые были в PATH до этого.

anonymous
()
Ответ на: комментарий от Datt_

И где написано, что bash, вызванный как interactive shell будет читать /etc/profile? Или считаете, что bash может быть запущен только эмулятором терминала?

Вы в терминале какие-нибудь программы, кроме mc запускали? Допустим less? В less можно не выходя запустить какую-нибудь команду, допустим ! ls -l. less вызовет bash, чтобы тот вызвал ″ls -l″. Это не будте login shell. less не обязан выставлять PATH...

mky ★★★★★
()
Ответ на: комментарий от anonymous

Это было бы справедливо, будь в этом пути что-то кроме /home/user/bin и /home/user/.local/bin . Но речь про дефолтные настройки в Centos 8. Если по какой-то причине PATH до этого не была проэкспортирована, то, полученная запись PATH=:/home/user/bin ничего не изменит. А значит ваша теория о защите от дурака не совсем подходит для конкретно этой ситуации.

Datt_
() автор топика
Ответ на: комментарий от Datt_

Откуда вы взяли, что будет

PATH=:/home/user/bin

я ведь привёл команды, показывающие что будет, если нет переменной окружения PATH.

mky ★★★★★
()
Ответ на: комментарий от mky

Выше была ссылка на ютуб канал, там стримов на часов 20, наверное. Если вы хоть в одном увидите mc, ваши слова не будут пустым вбросом.

Пример с less так себе, потому что попробуйте сделать ! echo $PATH и поймёте.

Опять же, давайте мне реальный пример со скриншотом про тот вопрос, который я задал - зачем в ~/.bashrc export PATH. То есть, вы утверждаете, что он какие-то программы, запущенные вне интерактивного шелла, не увидят переменную PATH без этой записи (~/.bashrc export PATH). Давайте я уберу этот export, а вы подскажите команды, чтобы я запустил или сами их запустите и пришлите скриншот. Когда я увижу, что будет разница между ситуациями, где этот export прописан и не прописан, я пойму.

Datt_
() автор топика
Последнее исправление: Datt_ (всего исправлений: 1)
Ответ на: комментарий от Datt_

Ну так что ты хочешь, там не sh, а bash, это «немного разные» командные оболочки, хоть и родственные.

Я вряд ли найду тебе сейчас где-то каноничный sh про который тебе говорили, потому что в большинстве нынешних реализаций это любой другой аналог. Но это не говорит о том, что ты не можешь его встретить в природе.

Да и уж прости, для того чтобы тебе доказать что-то, никто не будет чего-то искать и приводить примеры, тем более ты инициатор, так что бремя ответственности доказательства лежит на тебе, ты в принципе если бы не был троллем мог бы просто как нормальный человек почитать ответы и с некоторой степенью доверия принять их, тем более, что каждый из них логичный, но ты продолжаешь упираться оправдывая свой тупняк и искать какие-то доказательства того, что поведение по умолчанию для одного конкретного дистрибутива будет работать и для всех остальных. Тебе сказали что не будет, что ты еще хочешь? Не веришь, вперед устанавливай все доступные Unix и Unix-like ОС и проверяй.

Ну и достаточно легко загуглить что стандарты posix, что исходные тексты известных шеллов чтобы понять, кто и в какой мере из них поддерживает этот posix. Опять же стоит понимать что sh в его каноничном виде появился в 1977 году, а первые стандарты posix в 1988. Так что есть реализации sh которые вообще не удовлетворяют posix разве что так вышло что они ему удовлетворяют по той причине что эти стандарты писались с оглядкой на уже имеющееся окружение.

почему так написано

Ну во-первых надо ссылки кидать когда что-то цитируешь, далеко не каждый источник вызывает доверие. Во-вторых, это похоже на правду, в-третьих, что вызывает недоумение?

это не имеет значения, не важно, написано это в одном дистре или во всех.

что «это»?

Если речь о совместимости, пришлите скриншот, где вы не сделали export и все поломалось.

Читайте выше о бремени доказательства. Ну и у вас вообще какая-то поломанная логика, почему export должен что-то ломать? прочитайте уже man страницу export, поломать можете только вы что-то своими действиями, а экспорт просто экспортирует имя в окружение и не более.

Я вам уже раза 4 точно сказал для чего нужен экспорт, но вы упорно продолжаете настаивать на том, что раз в конкретном дистрибутиве при его инициализации за вас уже проэкспортировали PATH в окружение, а каждая новая сессия командной оболочки вытягивает заново эту инициализацию, то вроде как можно и не экспортировать ничего повторно, а просто править текущий PATH. Но это порочная практика завязанная на конкретный дистрибутив, пример с камерой я вам давал и если вы запорите там PATH восстановить его можно будет только перезапуском скриптов инициализации, т.е. считай перегрузить камеру, также вам давали понять что каноничный sh работает иначе в ряде случаев возможно и экскорт там работает иначе, это вопросы к любителям старины.

anonymous
()
Ответ на: комментарий от Datt_

Но речь про дефолтные настройки в Centos 8.

Вся суть вашего спича, сколько раз мне нужно повторить это чтобы вы поняли что где-то может быть иначе?

anonymous
()
Ответ на: комментарий от anonymous

Сколько раз мне повторять, что я знаю, что на других дистрах по-другому, но я спрашиваю про смысл этой надписи в Centos 8?

Datt_
() автор топика
Ответ на: комментарий от anonymous

У меня на работе есть AIX, проверю на нём. Но даже если это справедливо для каких-то древних юниксовых sh, какой смысл давать эту совместимость в Centos 8, при том, что этой записи нет в других дистрах, даже в Centos 7, судя по словам одного из отписавшихся. Хотя я это тоже проверю

Datt_
() автор топика
Ответ на: комментарий от Datt_

А теперь перечитайте свой изначальный пост, там нет ни слова про Centos 8 и конкретную завязанность на нем. Ты это начал использовать чтобы и дальше продолжать свой троллинг и иметь хоть какое-то оправдание тупняку. По факту тебе уже сказали для чего нужен повторный экспорт и почему его лучше писать чем не писать.

anonymous
()
Ответ на: комментарий от Datt_

смысл в том, что ты никогда не знаешь на какой целевой системе будут запускать твои скрипты, и лучше делать защиту от дурака чем ее не делать и закладываться на какое-то поведение.

anonymous
()
Ответ на: комментарий от anonymous

Как же с вами сложно. Потому что мой изначальный пост был про вопрос, нафига переменную среды повторно экспортить, в частности PATH. На что мне начали писать вообще ответы на несвязанные темы или вообще говорить, что в bashrc такого не пишут. Тогда я привёл пример, что вот Centos 8 так написано. Мне начали объяснять, что в других дистрах не так, вместо того, чтобы ответить на мой первый вопрос. Поэтому я всё упростил до максимально простого вопроса - зачем было экспорить path в одном только centos. Если кто-то объяснит хотя бы это, я получу ответ и на свой основной вопрос.

Теперь мне говорят, что «лучше писать, чем не писать». А тогда почему на других дистрах не пишут? Да и смысла в такой защите я просто не увидел. Хорошо, это защита на случай, если PATH не переменная среды. Как это защитит, ведь PATH получится бессмысленный (в случае с PATH, указанным в Сentos 8).

Datt_
() автор топика
Ответ на: комментарий от anonymous

Это справедливо для скриптов, но не для переменной PATH в ~/.bashrc. Причём здесь скрипты и export PATH в ~/.bashrc?

Datt_
() автор топика
Ответ на: комментарий от Datt_

Сколько ты там говоришь у тебя лет работы в unix окружении? Позволь тебе задать вопрос, является ли profile и bashrc скриптами?

В общем-то можешь не отвечать. Относительно твоего вопроса ты получил ответ.

anonymous
()
Ответ на: комментарий от anonymous

Эм, и часто вы видели, чтобы кто-то закидывал profile и bashrc с какого-нибудь Centos 8 на какой-нибудь Solaris?

Кстати, проверил на AIX. Всё работает без export (для тех, кто говорил для совместимости с sh) https://ibb.co/41yZc7C

Datt_
() автор топика
Ответ на: комментарий от Datt_

Это так не работает. В ядре, точнее во многих UN*X, давно сделано, что можно запустить файл без shebang (#!) и такой файл будет отдан на выполнение shell'ом. Что сломается, если это убрать из ядра? Да никто не знает, скорее всего, всё будет работать, но это не убирают. При этом везде написано, что скрипт обязательно должен начинаться с shebang.

Я не знаю конкретных примеров софта, который запускает /bin/bash без переменной среды PATH, может его такого в продакшене и нет, может это какая специфичная для RH поделка. Понятно, что там должна быть цепочка, что сначала запускается /bin/bash без PATH, а из него вызывается ещё что-то, которому нужно в PATH наличие ~/bin.

Считаете, что ″export PATH″ является багом — пишите в багзилу.

mky ★★★★★
()
Ответ на: комментарий от mky

Я не говорю что это баг, я не считаю, что чувак, который написал это в ~/.bashrc написал это просто так. Я просто хочу понять, зачем это сделано?

Ответы для совместимости с sh меня не убедили - проверил на AIX-овском shell, проверил на dash, на zsh - всё работает и без export.

Ответы «для защиты от случаев, если PATH не задалась как переменная среды» тоже не до конца понятны, потому что в таком случае мы получаем запись PATH=:/home/user/bin, а это не то чтобы спасает ситуацию. Всё равно что на отрезанную ногу пластырь накладывать.

Datt_
() автор топика
Ответ на: комментарий от Datt_

Я просто хочу понять, зачем это сделано?

По-привычке. Проще запомнить ‘везде пишем export’, чем ‘пишем экспорт кроме случаев «список из 25 системоспецифичных исключений»’.

ugoday ★★★★★
()
Ответ на: комментарий от ugoday

это локальные переменные и их экспорт.

Попробуйте с переменными окружения, которые уже заданы, например LANG.

echo $LANG

– en_US.UTF-8

LANG=ru_RU.UTF-8

echo $LANG

– ru_RU.UTF-8

sh

echo $LANG

– ru_RU.UTF-8

смысла в export просто нет, если это уже переменная среды

Datt_
() автор топика
Ответ на: комментарий от Datt_

смысла в export просто нет

Смысла менять привычки тоже нет.

ugoday ★★★★★
()
Ответ на: комментарий от Datt_

почему это нужно в Centos

ИМХО, потому что так в RHEL, а CentOS заявляет максимальную совместимость с RHEL. Почему так в RHEL — не знаю, может давно написали по какой-то причине, а потом менять не хочется, они ведь продают поддержку, вдруг у какого клиента дренее Ъ-энтерпрайз шняга от этого сломается. Не знаю.

мы получаем запись PATH=:/home/user/bin

У меня в gentoo при запуске bath без PATH получается:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/user/bin
Мне сейчас некуда ставить CentOS, да и вобще не хочется его устанавливать. То, что bash при запуске без PATH сам определит его я помню ещё в RH 7.0 (bash 2.05). Посмотрите вывод команды:
env -i bash -c 'echo $PATH'

mky ★★★★★
()
Ответ на: комментарий от mky

env -i bash -c ‘echo $PATH’

А вот за это спасибо, не знал. Теперь хотя бы понятно, что не будет PATH=:/home/user/bin, а будет

env -i bash -c 'PATH=$PATH:/home/usr/bin; echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/bin:/home/usr/bin

Насчёт совместимости с древним энтерпрайзом.. нууу, это мне не проверить, но окей, может звучать правдоподобно. Кстати, проверил, в Centos 7 эта надпись ( PATH=$PATH:$HOME/bin, export $PATH ) записана в ~/.bash_profile, хотя тоже есть строчка для чтения ~/.bashrc. Интересно, есть ли какой-то changelog с объяснением?

Datt_
() автор топика
Ответ на: комментарий от Datt_

кстати, у меня в .profile нет никакого export PATH

grep PATH ~/.profile 
# set PATH so it includes user's private bin if it exists
    PATH="$HOME/bin:$PATH"
# set PATH so it includes user's private bin if it exists
    PATH="$HOME/.local/bin:$PATH"

и всё

Возможно это старый .profile еще с 9 дебиана, а может и нет, не помню, хотя сейчас стоит arch, но home я не трогал при переезде. Не помню

Datt_
() автор топика
Последнее исправление: Datt_ (всего исправлений: 1)

это заграничный PATH. фарца.

buratino ★★★★★
()
Ответ на: комментарий от Datt_

И это как-то делает profile и bashrc меньше скриптами? Закинуть то можно, но зачем?

Теперь на всех вариациях всех систем со всеми вариантами командных оболочек. Типичный ты в своем упорстве доказать, что это не тупняк.

Кстати ваш AIX поди не самый протухший, postposix, не так ли?

anonymous
()
Ответ на: комментарий от anonymous

А я говорил, что profile не скрипт? Просто когда речь идет о posix скриптах, речь обычно идет не о profilе файле, а об административных скриптах. Можно конечно и profile ради этого делать posix совместимым, но за два дня я не нашел шелла, который бы не работал без export PATH. Да и как я привел пример, на том же дебиане этой записи нет. Хотите сказать, что разработчики дебиана не думают о шелл совместимости?

Datt_
() автор топика
Ответ на: комментарий от Datt_

предположу, что export сделан по незнанию "на всякий случай".
я например только в этом треде узнал что экспортированные переменные не надо повторно экспортировать при изменении, и я в profile прописывал export PATH.

teod0r ★★★★★
()
Ответ на: комментарий от gedisdone

нет, пробовал из баша в шелл, из баша в zsh и т.п. Переменные среды передаются

Datt_
() автор топика
Ответ на: комментарий от Datt_

Так ты вообще прямо не отвечаешь, тебя спрашивают одно ты отвечаешь другое и поди тебя пойми это ты так возражаешь или еще что-то, скрипты есть скрипты profile в твоей градации скриптов точно такой же «административный» скрипт потому что он непосредственно влияет на систему как и любой остальной. На твой изначальный вопрос для чего экспорт нужен тебе уже ответил не только я. Но ты прицепился именно к переменной окружения под названием PATH которая инициализируется первый раз когда загружается ядро и происходит первичная инициализация, потом уже дальше все остальные по пищевой цепи этот PATH используют в соответствии со своими нуждами и потребностями, будь то sysvinit или systemd или еще что-то другое. Выполни sudo strings /proc/1/environ и посмотри что уже там PATH задается (тут ты должен понять что это самый первый процесс). Но ничто не мешает мне например собрать все свое окружение и ядро так что PATH превратится в тыкву, а вместо нее у меня будет какой-нибудь MYPATH. И тогда твой PATH превратится в как ты это называешь «локальную переменную». Они все одинаковые, а не «локальные» просто система инициализации и запуска уж очень закладывается именно на эту, скорее всего по этому поводу даже есть какой-нибудь posix стандарт.

ты просто выбрал неудачный пример переменной окружения на основе которой хотел понять почему повторный экспорт это устоявшаяся практика, а надо было всего-то пописать скриптов со своими переменными которые бы ты экспортировал и посмотреть что будет если этого не делать, вот и всё, хотя тут уже и это сделали примеров вон накидали.

anonymous
()
Ответ на: комментарий от anonymous

Я привел примеры с LANG,С ним также не нужно экспорт, как и с любыми переменными среды.

Вы мне тут втираете про какое-то свое кастомное окружение со своим PATH, уж если кто-то это и сделает, то он и додумается себе прописать PATH и экспортнуть, не будут ради такого специфичного кейса в дефолтной системе писать лишнюю строчку.

Datt_
() автор топика
Ответ на: комментарий от Datt_

Тем что ты можешь поставить нужные права на /home/user/bin. А почему ты это не делаешь, это уже твои личные проблемы...

peregrine ★★★★★
()
Ответ на: комментарий от Datt_

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

Рассказывать надо так как есть, чтобы потом шаблон не рвался.

peregrine ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.