Вопрос по командам set, env, declare, export (В чем разница?)
Модератор: Модераторы разделов
-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Вопрос по командам set, env, declare, export
Не могу понять, чем объясняется разница в выводе команд set, env, export и declare (typeset). Вроде все они должны выводить перечень переменных среды (и функций), но вывод этих команд существенно отличается.
Может кто-нибудь толково объяснить, в чем их разница. В man-ах копался, но не понял.
В.Костромин
Может кто-нибудь толково объяснить, в чем их разница. В man-ах копался, но не понял.
В.Костромин
-
- Сообщения: 159
- ОС: AltLinux2.4 master
Re: Вопрос по командам set, env, declare, export
Внимательно читай маны. Это немножко разные команды, хотя каждая по своему работает с переменными.
Познание бесконечности требует бесконечного времени.
А. и Б. Стругацкие
Понедельник начинается в субботу
А. и Б. Стругацкие
Понедельник начинается в субботу
-
- Сообщения: 317
- ОС: ASP Linux 14
Re: Вопрос по командам set, env, declare, export
СЕйчас прийдут злые модераторы и доходчиво обьяснят как нужно отвечать на вопросы в этом разделе форума. Предлагаю самому исправить ситуацию и рассказать то что знаете по этой теме. Тем более спрашивает не кто-нибудь, а уважаемый человек который, скорее всего, не только из своего любопытства спрашивает, а хочет эту информацию препднести многим начинающим линуксоидам.
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Вопрос по командам set, env, declare, export
ОК. показ переменных среди для каждой из этих программ - это что-то типа дополнительного эффекта.
env - запускает программу в модифицированной среде, без дополнительных опций показывает переменные среды.
в меру моего понимания это примерно тоже самое что
TEST=test bash
но env не встроена в bash (поэтому с него и начал).
declare,typeset - синонимы. собственно объявляет переменные и устанавливает для них атриббуты. Из полезностей: -a - переменная - массив, -i рассматривать переменную как число, -r read-only, и еще несколько. built-in в bash. declare без параметров фактически показывает не только переменные и их значения, но все имена зарезервированные в данный момент в оболочке (т.е. и имена фунцкий например, а так же их значения)
export "помечает" переменную для експортирования в окружение запускаемых команд. Вот в таком ключе:
1. export показывает имена переменных в формате:
declare -x XTERM_SHELL="/bin/bash"
2. export показывает только переменные которые будут експортироваться в окружение запускаемой новой программы.
3. + фактически env и export показывают одни и те же результаты, за исключением наличия в выводе env странной переменной: _=/usr/bin/env .
set умеет делать много чего еще, без параметров показывает идетнификаторы и их значения (имена переменных, функций итп), в формате удобном для того чтобы потом их можно было переустановить. read-only переменные переустановить нельзя.
+ у мну получилось опять таки:
що ж это за переменная такая?
ЗЫ: модераторы не злые, здесь этому топику будет комфортней.
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
що ж это за переменная такая?
ЗЫ: модераторы не злые, здесь этому топику будет комфортней.
-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Re: Вопрос по командам set, env, declare, export
Все, что вы написали, я и сам обнаружил. Только вот четко понять, что показывает каждая из команд и в чем именно вывод export (когда без параметров она просто выводит перечень переменных среды) отличается от вывода set, я так и не понял. Ответ хотелось бы видеть примерно в таком виде:
- export выводит наследуемые (передаваемые) переменные;
- set выводит все определенные для данного экземпляра оболочки переменные и функции с их значениями;
- env без параметров - выводит текущее окружение запущенного экземпляра shell.
Примерно в таком виде, только подробнее и с обоснованиями (пояснениями). Приведенные ответы я, можно сказать, сейчас насочинял, как пример. Они не полны и в их истинности я не уверен. Может кто-то помочь.
PS. А ответ мне, действительно, нужен для того, чтобы подробно все изложить в сочиняемой в данный момент статье.
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Вопрос по командам set, env, declare, export
ЗЫ: в ходе експерементов - разница между (export,env) vs. (set,declare) очевидна, я про нее сказал. вот разница между собой очень призрачна.
казалось бы set не должен показывать read-only variables (я с мана описание взял), но он их показывает. то что не reset'ит - это понятна.
казалось бы set не должен показывать read-only variables (я с мана описание взял), но он их показывает. то что не reset'ит - это понятна.
-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Re: Вопрос по командам set, env, declare, export
О странной переменной _=/usr/bin/env я где-то в man-х встречал упоминание, это просто полное имя запущенной программы. Вы же получили вывод именно этой программы, в том числе и ее имя в переменной _.
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Вопрос по командам set, env, declare, export
ага, похоже в set это немного другое:
поэтому я и назвал ее странной.
ЗЫ: вообще спасибо за топик, ни разу не задумывался над этой проблемой, хотя shell каждый день вижу. надо до конца разобраться.
Код: Выделить всё
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 каждый день вижу. надо до конца разобраться.
-
- Сообщения: 317
- ОС: ASP Linux 14
Re: Вопрос по командам set, env, declare, export
Ничего против модераторов не имею против, наоборот уважаю их труд, и знаю что это такое (сам был администратором и по совместительству модератором на форуме в общежитии, объёмы работы конечно не те, но прелести прочувствовал)

-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Re: Вопрос по командам set, env, declare, export
Вот небольшая табличка показывающая объем файла и число строк в нем для 4 команд, каждая из которых должна вроде как выдавать состав текущего окружения (все запускались в одном и том же консольном окне, то есть в одинаковых условиях):
declare 3803 байта 77 строк
set 3776 байта 77 строк
export 3558 байта 67 строк
env 2861 байта 45 строк
Сравнивал вывод построчно, понять в чем причина отличий не могу.
Можете повторить эксперимент
declare 3803 байта 77 строк
set 3776 байта 77 строк
export 3558 байта 67 строк
env 2861 байта 45 строк
Сравнивал вывод построчно, понять в чем причина отличий не могу.
Можете повторить эксперимент
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Вопрос по командам set, env, declare, export
гм.
а можете файлы приложить?
diff между моими после некоторых манипуляций (удалить кавычки, declare -x, и sort):
между declare и set diff выше, попробовал в новом шеле - тоже самое.
Updated: вот еще на другом сервере попробовал:
mc я так понял всплыло с :
Код: Выделить всё
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
-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Re: Вопрос по командам set, env, declare, export
У вас нет необходимых прав для просмотра вложений в этом сообщении.
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Вопрос по командам set, env, declare, export
так и есть 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
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Вопрос по командам set, env, declare, export
в 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:\\
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Вопрос по командам set, env, declare, export
С дублированием в 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.
-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Re: Вопрос по командам set, env, declare, export
Одно существенное различие заметил: как раз в переменой "_" - в трех файлах она присутствет и равна, соответственно :
_=/usr/bin/env - в env
_=/usr/share/mc/bin/mc-wrapper.sh - в declare
_=set - в set
в выводе команды export такой переменой нет.
То есть мы получаем в каждом случае окружение соответствующего процесса, унаследованное от текущей оболочки. Если бы вывод отличался только в переменной _ все было бы ясно. А так получается, что запуск каждой команды добавляет что-то в окружение, причем у каждой команды эта добавка своя. Если бы еще общая часть совпадала с выводом команды экспорт. Это не получается. Если предположить, что export показывает наследуемые переменные, то неясно почему в env их меньше, чем в выводе export.
_=/usr/bin/env - в env
_=/usr/share/mc/bin/mc-wrapper.sh - в declare
_=set - в set
в выводе команды export такой переменой нет.
То есть мы получаем в каждом случае окружение соответствующего процесса, унаследованное от текущей оболочки. Если бы вывод отличался только в переменной _ все было бы ясно. А так получается, что запуск каждой команды добавляет что-то в окружение, причем у каждой команды эта добавка своя. Если бы еще общая часть совпадала с выводом команды экспорт. Это не получается. Если предположить, что export показывает наследуемые переменные, то неясно почему в env их меньше, чем в выводе export.
-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Re: Вопрос по командам set, env, declare, export
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 не задавал. Сами команды их выполняют что-ли. Тогда где описаны законы этого выполнения?
-
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: Вопрос по командам set, env, declare, export
переменная $_ - это последнее введенное слово.
Код: Выделить всё
[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
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
- Сообщения: 159
- ОС: AltLinux2.4 master
Re: Вопрос по командам set, env, declare, export
serge_m писал(а): ↑14.10.2007 14:28
СЕйчас прийдут злые модераторы и доходчиво обьяснят как нужно отвечать на вопросы в этом разделе форума. Предлагаю самому исправить ситуацию и рассказать то что знаете по этой теме. Тем более спрашивает не кто-нибудь, а уважаемый человек который, скорее всего, не только из своего любопытства спрашивает, а хочет эту информацию препднести многим начинающим линуксоидам.
Получилось действительно нех-хорошо.
Извиняюсь. Мнэээ... Меня вообще трудно обидеть, а в тех случаях, когда я явно не прав, как сейчас, критику всегда воспринимаю нормально.
Ко всему здесь сказаному добавить мне нечего. Собственно знаю не больше, чем написано в man bash, Advansed Bash-Scripting Guide. О различиях в выводе команд без параметров никогда не задумывался. Из хода обсуждения могу только предположить что причину можно найти не иначе, как посмотрев исходники

Познание бесконечности требует бесконечного времени.
А. и Б. Стругацкие
Понедельник начинается в субботу
А. и Б. Стругацкие
Понедельник начинается в субботу
-
- Сообщения: 160
- Статус: продвинутый пользователь Linux
- ОС: Mandriva Linux
Re: Вопрос по командам set, env, declare, export
Немного дополню о результатах своих изысканий.
Во-первых, перезапустил систему на 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."
То есть тут уже окружение определяется несколькими последовательно запускаемыми процессами, и кто что установил, надо разбираться отдельно.
Во-первых, перезапустил систему на 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."
То есть тут уже окружение определяется несколькими последовательно запускаемыми процессами, и кто что установил, надо разбираться отдельно.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
-
- Сообщения: 159
- ОС: AltLinux2.4 master
Re: Вопрос по командам set, env, declare, export
Может быть поможет (из man bash)?
_ При запуске командного интерпретатора устанавливается равным
полному имени файла (absolute file name) командного
интерпретатора или выполняемого сценария, переданного в списке
аргументов. В последствии, заменяется последним аргументом
предыдущей команды, с учетом всех замен. Также устанавливается
равным полному имени файла каждой выполняемой внешней команды и
помещается в среду, экспортируемую для этой команды. При
проверке почты этот параметр содержит имя проверяемого файла
почты.
Познание бесконечности требует бесконечного времени.
А. и Б. Стругацкие
Понедельник начинается в субботу
А. и Б. Стругацкие
Понедельник начинается в субботу
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
-
- Сообщения: 357
- ОС: GNU/Linux 4.x (Fedora, Debian)
Re: Вопрос по командам set, env, declare, export
Старая тема, а не понятно.
Как присвоить локальную переменную?
Как присвоить глобальную переменную?
Как присвоить локальную переменную?
Как присвоить глобальную переменную?