Я знаю, env
что это команда оболочки, она может быть использована для печати списка текущих переменных среды. И, насколько я понимаю, RANDOM
это тоже переменная окружения.
Итак, почему, когда я запускаю env
на Linux, выходные данные не включают RANDOM
?
shell
environment-variables
mcmxciv
источник
источник
env
не является командой оболочки, так как обычно она не встроена в оболочку.declare -x
является эквивалентом встроенной оболочки.Ответы:
RANDOM
не является переменной среды Это переменная оболочки, поддерживаемая некоторыми оболочками. Обычно он не экспортируется по умолчанию. Вот почему он не отображается на выходеenv
.Как только он будет использован хотя бы один раз, он будет отображаться в выходных данных
set
, которые сами по себе перечисляют переменные оболочки (и функции) и их значения в текущем сеансе оболочки. Это поведение зависит от оболочки и использованияpdksh
в OpenBSD,RANDOM
будет перечислено,set
даже если ранее не использовался.Остальная часть этого ответа касается того, что могло бы произойти, если бы он
RANDOM
был экспортирован (то есть превращен в переменную окружения).Экспорт с помощью
export RANDOM
этого сделает переменную окружения, но его использование будет строго ограничено, поскольку его значение в дочернем процессе будет «случайным, но статическим» (то есть это будет неизменное случайное число). Точное поведение отличается между оболочками.Я использую
pdksh
OpenBSD в приведенном ниже примере и получаю новое случайное значение при каждомawk
запуске (но одно и то же значение каждый раз в одном и том жеawk
экземпляре). Используяbash
, я бы получил абсолютно одинаковое случайное значение во всех вызовахawk
.В
bash
, экспортированное значениеRANDOM
будет оставаться статическим независимо от использованияRANDOM
в оболочке (где каждое использование по-$RANDOM
прежнему дает новое значение).Это происходит потому , что каждая ссылка на переменную оболочки
RANDOM
вbash
делает доступ к оболочке его внутренняяget_random()
функция , чтобы дать переменной новое случайное значение, но оболочка не обновляет переменную окруженияRANDOM
. По поведению это похоже на другие динамическиеbash
переменные, такие какLINENO
,SECONDS
иBASHPID
т. Д.Чтобы обновить переменные среды
RANDOM
вbash
, вы должны присвоить ему значение переменной оболочкиRANDOM
и реэкспорт:Мне неясно, будет ли это иметь дополнительный побочный эффект повторного заполнения генератора случайных чисел
bash
или нет (но образованное предположение будет, что это не так).источник
RANDOM
даже значение, прежде чем использовать его? Я всегда предполагал, что это было только заполнено, когда названо.export RANDOM
илиdeclare -p RANDOM
, кажется, так что я не уверен, есть ли какая-то польза от того, что он не существует до того, как на него ссылаются ...Не все переменные, которые установлены в вашем сеансе оболочки, являются переменными среды. «Переменные среды» относятся только к тем переменным, которые были экспортированы в среду с помощью
export
встроенной функции.env
печатает только такие переменные среды . Например:Если вы хотите увидеть все переменные, установленные в вашем сеансе, независимо от того, были ли они экспортированы, вы можете использовать
set
:set
Встроенный также возвращает функцию, так , чтобы видеть только переменные, вы можете использовать:Наконец,
RANDOM
переменная является особенной в том смысле, что ей присваивается значение только при ссылке на нее Это упоминается в bash (1) :Таким образом, даже если бы это была переменная окружения, как вы думали, она бы не отображалась,
env
поскольку не будет установлена до тех пор, пока вы не вызовете ее в первый раз. Это также, почему это не показано вset
:источник
set | grep RAN
. Я бы не ожидал этого. FWIW, я считаю, что это не может быть предсказано документацией.У большинства оболочек есть ряд других переменных, установленных или используемых оболочкой, которые по умолчанию не экспортируются в дочерние процессы.
В Bash есть некоторые, очевидно, специфичные для Bash:
Тогда есть более стандартные, такие как
OPTIND
andOPTERR
(используетсяgetopts
), andPS2
,PS3
(вторичные запросы) и даже другая «магическая» переменная:SECONDS
(показывает время в секундах с момента запуска оболочки)В Bash вы можете видеть все переменные и их статус экспорта с помощью
declare -p
. Те , отмеченные-x
экспортируются, те , безx
не. (У некоторых будут другие флаги, например,i
для целого числа или толькоr
для чтения.)В Zsh или ksh93 вы можете использовать
typeset -p
, хотя Zsh помечает экспортируемые переменные, заменяяtypeset
ихexport
на выходные, вместо использования флагов.export
сам по себе также будет отображать все экспортированные переменные, но это примерно тот же результат, который вы получите при запускеenv
.источник
Если вы гуглите по этому поводу, документы сообщат следующее:
Если вы используете,
strace
вы можете видеть, что$RANDOM
«переменная» передается непосредственно командам, как если бы это была обычная переменная оболочки или переменная окружения, но это просто внутренняя функция, встроенная в оболочку, Bash, которая выполняет расширение.против этой регулярной переменной:
Переменная не передается в качестве ссылки.
Ссылки
источник
$RANDOM
или$SOMEVAR
через аргумент командной строки, а не как переменная окружения? Вы должныexport
оба, чтобы передать их через окружающую среду.strace
Выход , кажется, не поймать внутреннюю функцию запуска оболочки. В обоих случаях переменная уже раскрыта в первой строкеstrace
. Я не понимаю, на какую разницу вы указываете. Чего мне не хватает?$RANDOM
расширение выполняется внутри оболочки. По сути, это подтверждение того, что оболочка определяет значение, а не передает ссылку на переменную. Оболочка при расширении командной строки для выполнения анализа$RANDOM
и передачи расширенной формыecho
.