Вопрос по командам set, env, declare, export (В чем разница?)

Модератор: Модераторы разделов

Ответить
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Вопрос по командам set, env, declare, export

Сообщение vikos »

Не могу понять, чем объясняется разница в выводе команд set, env, export и declare (typeset). Вроде все они должны выводить перечень переменных среды (и функций), но вывод этих команд существенно отличается.
Может кто-нибудь толково объяснить, в чем их разница. В man-ах копался, но не понял.
В.Костромин
Спасибо сказали:
Аватара пользователя
Славик
Сообщения: 159
ОС: AltLinux2.4 master

Re: Вопрос по командам set, env, declare, export

Сообщение Славик »

Внимательно читай маны. Это немножко разные команды, хотя каждая по своему работает с переменными.
Познание бесконечности требует бесконечного времени.
А. и Б. Стругацкие
Понедельник начинается в субботу
Спасибо сказали:
Аватара пользователя
serge_m
Сообщения: 317
ОС: ASP Linux 14

Re: Вопрос по командам set, env, declare, export

Сообщение serge_m »

Славик писал(а):
14.10.2007 14:02
Внимательно читай маны. Это немножко разные команды, хотя каждая по своему работает с переменными.

СЕйчас прийдут злые модераторы и доходчиво обьяснят как нужно отвечать на вопросы в этом разделе форума. Предлагаю самому исправить ситуацию и рассказать то что знаете по этой теме. Тем более спрашивает не кто-нибудь, а уважаемый человек который, скорее всего, не только из своего любопытства спрашивает, а хочет эту информацию препднести многим начинающим линуксоидам.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

ОК. показ переменных среди для каждой из этих программ - это что-то типа дополнительного эффекта.

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

Код: Выделить всё

diesel@beezir:~$ env TEST=bash bash
diesel@beezir:~$ echo $TEST
bash
diesel@beezir:~$ exit

в меру моего понимания это примерно тоже самое что
TEST=test bash
но env не встроена в bash (поэтому с него и начал).

declare,typeset - синонимы. собственно объявляет переменные и устанавливает для них атриббуты. Из полезностей: -a - переменная - массив, -i рассматривать переменную как число, -r read-only, и еще несколько. built-in в bash. declare без параметров фактически показывает не только переменные и их значения, но все имена зарезервированные в данный момент в оболочке (т.е. и имена фунцкий например, а так же их значения)

export "помечает" переменную для експортирования в окружение запускаемых команд. Вот в таком ключе:

Код: Выделить всё

diesel@beezir:~$ TEST=bash
diesel@beezir:~$ bash
ediesel@beezir:~$ echo $TEST

diesel@beezir:~$ exit
diesel@beezir:~$ export TEST
diesel@beezir:~$ bash
diesel@beezir:~$ echo $TEST
bash


1. export показывает имена переменных в формате:
declare -x XTERM_SHELL="/bin/bash"
2. export показывает только переменные которые будут експортироваться в окружение запускаемой новой программы.
3. + фактически env и export показывают одни и те же результаты, за исключением наличия в выводе env странной переменной: _=/usr/bin/env .

set умеет делать много чего еще, без параметров показывает идетнификаторы и их значения (имена переменных, функций итп), в формате удобном для того чтобы потом их можно было переустановить. read-only переменные переустановить нельзя.

+ у мну получилось опять таки:

Код: Выделить всё

diesel@beezir:~$ declare >1
diesel@beezir:~$ set >2
diesel@beezir:~$ diff 1 2
60c60
< _=env
---
> _=declare

що ж это за переменная такая?
ЗЫ: модераторы не злые, здесь этому топику будет комфортней.
Спасибо сказали:
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение vikos »

diesel писал(а):
14.10.2007 14:34
ОК. показ переменных среди для каждой из этих программ - это что-то типа дополнительного эффекта.

env - запускает программу в модифицированной среде, без дополнительных опций показывает переменные среды.
Все, что вы написали, я и сам обнаружил. Только вот четко понять, что показывает каждая из команд и в чем именно вывод export (когда без параметров она просто выводит перечень переменных среды) отличается от вывода set, я так и не понял. Ответ хотелось бы видеть примерно в таком виде:
- export выводит наследуемые (передаваемые) переменные;
- set выводит все определенные для данного экземпляра оболочки переменные и функции с их значениями;
- env без параметров - выводит текущее окружение запущенного экземпляра shell.

Примерно в таком виде, только подробнее и с обоснованиями (пояснениями). Приведенные ответы я, можно сказать, сейчас насочинял, как пример. Они не полны и в их истинности я не уверен. Может кто-то помочь.
PS. А ответ мне, действительно, нужен для того, чтобы подробно все изложить в сочиняемой в данный момент статье.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

ЗЫ: в ходе експерементов - разница между (export,env) vs. (set,declare) очевидна, я про нее сказал. вот разница между собой очень призрачна.
казалось бы set не должен показывать read-only variables (я с мана описание взял), но он их показывает. то что не reset'ит - это понятна.
Спасибо сказали:
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение vikos »

diesel писал(а):
14.10.2007 14:34
3. + фактически env и export показывают одни и те же результаты, за исключением наличия в выводе env странной переменной: _=/usr/bin/env .


О странной переменной _=/usr/bin/env я где-то в man-х встречал упоминание, это просто полное имя запущенной программы. Вы же получили вывод именно этой программы, в том числе и ее имя в переменной _.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

ага, похоже в set это немного другое:

Код: Выделить всё

diesel@beezir:~$ set |grep _=
_=/etc/bash_completion
diesel@beezir:~$ TEST=test
diesel@beezir:~$ set |grep _=
_=
diesel@beezir:~$ export TEST
diesel@beezir:~$ set |grep _=
_=TEST

поэтому я и назвал ее странной.

ЗЫ: вообще спасибо за топик, ни разу не задумывался над этой проблемой, хотя shell каждый день вижу. надо до конца разобраться.
Спасибо сказали:
Аватара пользователя
serge_m
Сообщения: 317
ОС: ASP Linux 14

Re: Вопрос по командам set, env, declare, export

Сообщение serge_m »

diesel писал(а):
14.10.2007 14:34
ЗЫ: модераторы не злые, здесь этому топику будет комфортней.

Ничего против модераторов не имею против, наоборот уважаю их труд, и знаю что это такое (сам был администратором и по совместительству модератором на форуме в общежитии, объёмы работы конечно не те, но прелести прочувствовал) :) Никого не хотел обидеть.
Спасибо сказали:
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение vikos »

Вот небольшая табличка показывающая объем файла и число строк в нем для 4 команд, каждая из которых должна вроде как выдавать состав текущего окружения (все запускались в одном и том же консольном окне, то есть в одинаковых условиях):

declare 3803 байта 77 строк
set 3776 байта 77 строк
export 3558 байта 67 строк
env 2861 байта 45 строк

Сравнивал вывод построчно, понять в чем причина отличий не могу.
Можете повторить эксперимент
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

гм.

Код: Выделить всё

diesel@beezir:~$ wc -l e*
  26 env
  26 export


а можете файлы приложить?

diff между моими после некоторых манипуляций (удалить кавычки, declare -x, и sort):

Код: Выделить всё

 diesel@beezir:~$ diff env export
13c13
<
---
> OLDPWD
27d26
< _=/usr/bin/env


между declare и set diff выше, попробовал в новом шеле - тоже самое.

Updated:
вот еще на другом сервере попробовал:

Код: Выделить всё

$ diff env export
1d0
< }
38d36
< mc=() {  . /usr/share/mc/bin/mc-wrapper.sh
41a40
> OLDPWD
57d55
< _=/usr/bin/env


mc я так понял всплыло с :

Код: Выделить всё

$ cat /etc/profile.d/mc.sh
mc ()
{
. /usr/share/mc/bin/mc-wrapper.sh
}
if [ -n "$BASH_VERSION" ]
then
    export -f mc
fi
Спасибо сказали:
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение vikos »

diesel писал(а):
14.10.2007 15:35
а можете файлы приложить?

Не жалко
Вложения
set.txt
(3.69 КБ) 30 скачиваний
export.txt
(3.47 КБ) 32 скачивания
env.txt
(2.79 КБ) 34 скачивания
declare.txt
(3.71 КБ) 29 скачиваний
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

так и есть export просто так не показывает експортируемые функции:

Код: Выделить всё

diesel@beezir:~$ export >export
diesel@beezir:~$ export TEST=123
diesel@beezir:~$ export > export.new
diesel@beezir:~$ env > env.new
diesel@beezir:~$ diff export export.new
20a21
> declare -x TEST="123"
diesel@beezir:~$ diff env env.new
17a18
> TEST=123
diesel@beezir:~$ func(){ echo "test"; }
diesel@beezir:~$ export -f func
diesel@beezir:~$ export > export.new1
diesel@beezir:~$ env > env.new1
diesel@beezir:~$ diff env.new env.new1
26a27,28
> func=() {  echo "test"
> }
diesel@beezir:~$ diff export.new export.new1
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

vikos писал(а):
14.10.2007 15:56
diesel писал(а):
14.10.2007 15:35
а можете файлы приложить?

Не жалко

в export у Вас почему-то переменные дублируются, после модификаций разница получилась вот такая:

Код: Выделить всё

diesel@beezir:~$ diff env.vik export.vik.uniq
36c36
< TERMCAP=SC|screen|VT 100/ANSI X3.64 virtual terminal:...много букв....
---
> TERMCAP=SC|screen|VT 100/ANSI X3.64 virtual terminal:\\
44c44
< _=/usr/bin/env
---
> XMODIFIERS=@im=none:\\
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

С дублированием в man'е есть примерно такое:

Functions
may be exported so that subshells automatically have them defined with
the -f option to the export builtin. Note that shell functions and
variables with the same name may result in multiple identically-named
entries in the environment passed to the shell’s children. Care should
be taken in cases where this may cause a problem.

правда че-то непонятно почему тк может получится.

разве что что-то с чем-то плюсуется:

Код: Выделить всё

 The environment inherited by any executed command
       consists of the shell’s initial environment, whose values may be  modi‐
       fied  in  the  shell, less any pairs removed by the unset command, plus
       any additions via the export and declare -x commands.
Спасибо сказали:
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение vikos »

Одно существенное различие заметил: как раз в переменой "_" - в трех файлах она присутствет и равна, соответственно :
_=/usr/bin/env - в env

_=/usr/share/mc/bin/mc-wrapper.sh - в declare

_=set - в set

в выводе команды export такой переменой нет.
То есть мы получаем в каждом случае окружение соответствующего процесса, унаследованное от текущей оболочки. Если бы вывод отличался только в переменной _ все было бы ясно. А так получается, что запуск каждой команды добавляет что-то в окружение, причем у каждой команды эта добавка своя. Если бы еще общая часть совпадала с выводом команды экспорт. Это не получается. Если предположить, что export показывает наследуемые переменные, то неясно почему в env их меньше, чем в выводе export.
Спасибо сказали:
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение vikos »

diesel писал(а):
14.10.2007 16:21

Код: Выделить всё

 The environment inherited by any executed command
       consists of the shell’s initial environment, whose values may be  modi‐
       fied  in  the  shell, less any pairs removed by the unset command, plus
       any additions via the export and declare -x commands.

При запуске команд я никаких unset, export и declare не задавал. Сами команды их выполняют что-ли. Тогда где описаны законы этого выполнения?
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение Portnov »

переменная $_ - это последнее введенное слово.

Код: Выделить всё

[portnov]$ ls rules
rules
[portnov]$ echo $_
rules
[portnov]$ echo xin*
xinitrc
[portnov]$ echo $_
xin*
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
Аватара пользователя
Славик
Сообщения: 159
ОС: AltLinux2.4 master

Re: Вопрос по командам set, env, declare, export

Сообщение Славик »

serge_m писал(а):
14.10.2007 14:28
Славик писал(а):
14.10.2007 14:02
Внимательно читай маны. Это немножко разные команды, хотя каждая по своему работает с переменными.

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


Получилось действительно нех-хорошо.
Извиняюсь. Мнэээ... Меня вообще трудно обидеть, а в тех случаях, когда я явно не прав, как сейчас, критику всегда воспринимаю нормально.

Ко всему здесь сказаному добавить мне нечего. Собственно знаю не больше, чем написано в man bash, Advansed Bash-Scripting Guide. О различиях в выводе команд без параметров никогда не задумывался. Из хода обсуждения могу только предположить что причину можно найти не иначе, как посмотрев исходники :wacko:
Познание бесконечности требует бесконечного времени.
А. и Б. Стругацкие
Понедельник начинается в субботу
Спасибо сказали:
vikos
Сообщения: 160
Статус: продвинутый пользователь Linux
ОС: Mandriva Linux
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение vikos »

Немного дополню о результатах своих изысканий.
Во-первых, перезапустил систему на 3 уровень выполнения, то есть вошел просто в оболочку, без всякого графического окружения. Повторил эксперимент с выводом 4 команд, получил немного другие результаты. Свел вывод в табличку, предварительно отсортировав. Получилось то, что вы можете просмотреть в прилагаемом файле (чтобы файл стал читаемым, пришлось несколько строк разбить на подстроки).
То есть команды export и env дают примерно одинаковый результат, а вывод пары set и declare совпадает с точностью до переменной _ (утверждение о том, что это последнее введенное слово, не подтверждается).
Так что я пока что полагаю, что первая пара дает наследуемые переменные, а вторая - полный список. Это для регистрационного шелла.

Поиск в Интернете дал еще следующий результат. Когда мы грузимся в графику сразу (уровень 5), то получаем не регистрационный шелл, а сначала грузится xdm
"Depends on how you start the X server. If you start it after you have logged in by using a command like startx, then the X server is started after you have logged in (duh). If it is started by xdm, for example, then it is started before you logged in."
То есть тут уже окружение определяется несколькими последовательно запускаемыми процессами, и кто что установил, надо разбираться отдельно.
Вложения

[Расширение html было запрещено, вложение больше недоступно.]

Спасибо сказали:
Аватара пользователя
Славик
Сообщения: 159
ОС: AltLinux2.4 master

Re: Вопрос по командам set, env, declare, export

Сообщение Славик »

Может быть поможет (из man bash)?

_ При запуске командного интерпретатора устанавливается равным
полному имени файла (absolute file name) командного
интерпретатора или выполняемого сценария, переданного в списке
аргументов. В последствии, заменяется последним аргументом
предыдущей команды, с учетом всех замен. Также устанавливается
равным полному имени файла каждой выполняемой внешней команды и
помещается в среду, экспортируемую для этой команды. При
проверке почты этот параметр содержит имя проверяемого файла
почты.
Познание бесконечности требует бесконечного времени.
А. и Б. Стругацкие
Понедельник начинается в субботу
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение diesel »

vikos писал(а):
14.10.2007 21:41
Так что я пока что полагаю, что первая пара дает наследуемые переменные, а вторая - полный список. Это для регистрационного шелла.

ну да. я об этом вначале говорил.
Спасибо сказали:
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Re: Вопрос по командам set, env, declare, export

Сообщение sunny1983 »

Старая тема, а не понятно.
Как присвоить локальную переменную?
Как присвоить глобальную переменную?
Спасибо сказали:
Ответить