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)

Ответ на: комментарий от peregrine

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

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

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

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

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

LANG и С экспортируются до того как ты войдешь в систему, это такие же системнозначимые переменные окружения как и PATH. Поотрубай все что запускает и инициализирует systemd (в том числе и локаль) и посмотришь как твой LANG тоже превратится в тыкву. Скорее всего и с C будет аналогичная ситуация.

можешь просто погрепать systemd-logind или как там он в centos называется через ps и точно так же запустить cat /proc/PID_systemd-logind/environ и убедиться что там уже и LANG и LANGUAGE на тот момент будут определены, а это ты еще даже в систему не зашел. T.e. чтобы ты там не делал залогинившись в системе у тебя все эти переменные окружения уже были проэкспортированы заранее.

Такое чувство складывается что ты тут нам в уши льешь про свой богатый опыт использования unix и linux в частности или ты в ней просто картинки с котиками смотрел.

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

Вы либо не поняли мой вопрос, либо не прочли ссылку. Зачем расширять переменную я знаю. Зачем ее повторно экспортить - нет

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

Кошмар. Я про Ивана, вы про болвана, еще и наезжаете на меня за это.

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

Хорошо, сделаю через час, как буду дома. Чтобы вы перестали переводить стрелки на смысл переменных, а обратили внимание на мой вопрос.

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

В такой ситуации повторный export PATH может разве что местным экспертам настроение поднять

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

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

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

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

Вот отрывок из мана классического Bourne shell в Солярке. В последнем предложении написано, зачем нужен export при модификации параметров.

  Environment
     The environment (see environ(5)) is  a  list  of  name-value
     pairs  that is passed to an executed program in the same way
     as a normal argument list.  The  shell  interacts  with  the
     environment  in several ways. On invocation, the shell scans
     the environment and creates a parameter for each name found,
     giving  it the corresponding value. If the user modifies the
     value of any of these parameters or creates new  parameters,
     none of these affects the environment unless the export com-
     mand is used to bind the shell's parameter to  the  environ-
     ment  (see also set -a).

А вот отрывок из Bash:

ENVIRONMENT
       When  a  program  is invoked it is given an array of strings called the environment.
       This is a list of name-value pairs, of the form name=value.

       The shell provides several ways to manipulate the environment.  On  invocation,  the
       shell  scans  its own environment and creates a parameter for each name found, auto-
       matically marking it for export to child processes.

Т.е. Bourne shell при старте сканирует переменные окружения, и для каждой из них создает свой собственный параметр.

Именно с этими параметрами ты и работаешь, когда указываешь $VAR.

Bash вдобавок еще и экспортирует все параметры, созданные из переменных окружения, а вот Bourne shell - нет. При модификации параметра он не попадет в окружение дочернего процесса, если для него не сделан экспорт.

Фактически .bashrc написан в стиле Bourne shell.
Запрещается ли писать на bash в стиле Bourne shell?
Я думаю нет. Некоторые люди терпеть не могут башизмы.

И минусов в таком подходе я не вижу.
Тебе нужно, чтобы дочерние процессы увидели переменную? Экспортируй ее, и дело с концом.

Зачем предполагать, что данная переменная уже есть в окружении, и bash автоматически экспортирует ее?
Мало ли что может поменяться в окружении, да и в самом Bash?
Например, до версии ~2.05b bash вообще экспортировал все свои специальные переменные, даже если их не было в окружении. Потом это убрали.

Чем меньше предположений делает скрипт, тем лучше. Это делает скрипт более устойчивым, т.е. он выполнит свои функции в неожиданных условиях, которые выходят за рамки предположений разработчика, столь же хорошо, как и в нормальных условиях.

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

Для меня это звучит как «В России все должны знать старославянский, потому что мало ли каким-нибудь образом, но вдруг в современной России появятся древние славяне, и будет обидно, что при их неожиданном появлении кто-то не ответит на их слова на старославянском.».

Ладно, допустим, есть такой бзик, что это нужно делать. Тогда почему в Debian так не сделали? В Debian дураки?

Еще и тут говорят, и в инете, и логически, правильнее переменную PATH держать в ~/.bash_profile, а в Centos 8 (и скорее всего в RHEL 8) она оказалась в ~/.bashrc. То есть разработчики решили держать совместимость с bourne shell, который еще откопать надо для Centos, но при этом внезапно решили перенести PATH в ~/.bashrc ?

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

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

Не читай всякие глупости в интернете =)

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

Если тебе это так интересно, то скачай исходники пакетов CentOS и Debian. Почитай ChangeLog’и, посмотри пачти, которые накладывают мантейнеры, их списки рассылки.

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

Ну из того что я понял, в bourne shell нет автоматического экспорта, из-за чего после изменения значения переменной окружения это никак не скажется на переменной окружения, а чтобы сказалось - нужно вручную экспортить.

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

Но это ломает мне логику вот в чём -

When a program is invoked it is given an array of strings called the environment.

Когда программа запускается, ей передаются переменные, называемые окружением.

Т.е. окружением называются переменные, задаваемые программе при запуске. И это мне говорил кто-то в другом месте. НО! в строчке bourne shell

none of these affects the environment unless the export com mand

сказано, что изменения переменной не повлияют на окружение, пока не сделать экспорт. Но как можно повлиять на окружение, если программа уже запущена? То есть её окружение уже задано.

А export «добавляет» переменную в окружение будущих дочерних процессов, но не в текущее окружение.

Как-то всё это запутано. То на окружение влиять нельзя, потому что оно задано при запуске, можно влиять только на окружения дочерних, то «не будет изменений в окружении, пока вы не сделаете export». Но ведь и при этой ситуации тоже не будет изменений в окружении..

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

Программа может модифицировать свое окружение - man putenv.

Но эффективнее засосать окружение в свои собственные переменные и потом уже работать с ними.

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

Спасибо! Вы для меня прояснили пару вещей. Я решил написать в centos mailing lists, посмотрим что ответят там. Хотя понимаю, что наверняка это сделали RHEL, но думаю они разберутся между собой.

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

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

Возможно ты не знаешь как создаются новые процессы, но об этом можно уже было догадаться, что в данном случае это форк (хотя есть еще например экзек который не копирует окружение своего родителя) и что все окружение от родительского процесса переезжает в дочерний, от того у тебя и выходит ненужность export для волшебных PATH C LANG и т.д. так как они проэкспортированы уже задолго до этого в окружение, вот и вся любовь. Тут ты можешь опять же начать вопрошаться вопросом, так какого же рожна они занимаются этим богомерзким для тебя экспортом, на что я тебе в десятый раз скажу, что это превентивный код, на случай если что-то пойдет не так как задумано высшим замыслом или просто изменится ситуация. Ты требуешь примеров, я тебе их привожу, но ты их не замечаешь и отмахиваешься от них. Ну и если все еще не понятно, вот последнее китайское пояснение в виде кусочка man:

ENVIRON(7)                Linux Programmer's Manual               ENVIRON(7)
NAME         top
       environ - user environment
SYNOPSIS         top
       extern char **environ;
DESCRIPTION         top
       The variable environ points to an array of pointers to strings called
       the "environment".  The last pointer in this array has the value
       NULL.  (This variable must be declared in the user program, but is
       declared in the header file <unistd.h> if the _GNU_SOURCE feature
       test macro is defined.)  This array of strings is made available to
       the process by the exec(3) call that started the process.  When a
       child process is created via fork(2), it inherits a copy of its
       parent's environment.

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

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

Господин истребитель крапивы, про «переменные окружения» я уже знаю и судя по моим комментам, вы могли это тоже увидеть. Мой вопрос был в смысле вторичного экспортирования переменных окружения, вы ответили про превентивные меры. Я понял вашу точку зрения, но не до конца согласился с ней, потому что вы не привели официальных пруффов от каких-нибудь разработчиков RHEL, где бы говорилось, что да, мы вот второй раз прописали это для превентивных мер. Да пусть даже не от Red Hat, а от какого-нибудь OpenSuse или хоть кого-нибудь. Просто мне кажется, что в случае, когда PATH внезапно не стал переменной среды до чтения ~/.bashrc, в системе проблемы посерьезнее и прикрытие их в ~/.bashrc, которое предполагает, что это будет работать только у юзера, никак не «предотвратит» проблему.

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

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

Я точно не уверен, но кажется в знаменитом руководстве по программированию bash есть подобные слова те что ты так вожделеешь прочитать не от анонима на лоре.

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