Как вы определяете, экспортируются ли переменные оболочки или нет?

13

В семействе оболочек Bourne все переменные оболочки имеют имена в верхнем регистре; Это означает, что вы не можете определить, является ли конкретная переменная переменной среды или нет, просто взглянув на ее имя. Как определить, какие переменные оболочки Bourne являются локальными (определены только в текущей оболочке)?

Shoulderpadz
источник
4
Оболочка Борна или Оболочка Борна? Можете ли вы указать ссылку на переменную в верхнем регистре?
Джефф Шаллер
В оболочке Bourne-again, поскольку все переменные являются прописными, как вы можете определить, какие переменные bash являются локальными?
Shoulderpadz
7
@Shoulderpadz ничто не мешает вам создавать строчные переменные.
Муру,
1
Под локальными вы подразумеваете переменные, которые не были экспортированы?
Элия ​​Каган,
4
Различие, о котором вы спрашиваете, - это переменные оболочки и переменные среды, а не глобальные и локальные. Обратите внимание, что есть переменные оболочки, которые не являются переменными среды (т. Е. То, что вы называете «локальным»), и есть переменные среды, которые не являются переменными оболочки (среда может содержать имена, которые не являются допустимыми идентификаторами оболочки, и поэтому не может быть переменными).
17

Ответы:

17

Если вы хотите увидеть, экспортируется ли переменная или нет, используйте declare:

$ foo=a bar=b
$ export foo
$ declare -p foo bar
declare -x foo="a"
declare -- bar="b"
Мур
источник
26

Самый переносимый способ есть export -p.

export -pсписки экспортируемых переменных. Обычно это так declare -x, если ваша оболочка имеет declare.

Оболочки в стиле Борна, используемые в настоящее время, должны поддерживать export -p, как того требует POSIX :

Если указана опция -p , при экспорте в стандартный вывод записываются имена и значения всех экспортируемых переменных в следующем формате:

"export %s=%s\n", <name>, <value>

если имя установлено, и:

"export %s\n", <name>

если имя не установлено.

Далее в стандарте поясняется, что значение переменной отображается таким образом, что обычно позволяет использовать его позже в правой части =присвоения. Это означает, что это может быть указано. Разные оболочки могут отображать их по-разному, но с одинаковым эффектом. export -pработает даже в оболочках, которые не имеют declareвстроенных функций, таких как Dash .

$ dash -c 'export -p | grep HOME='  # busybox sh and other ash give the same output.
export HOME='/home/ek'
$ posh -c 'export -p | grep HOME='  # ksh93, mksh, lksh, and others give the same output.
export HOME=/home/ek

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

Некоторые оболочки, такие как Bash, используют нестандартный формат, если явно не указано, что они должны вести себя POSIX-совместимым образом. В Bash export -pвыдает тот же вывод, что и declare -xпо умолчанию.

$ bash -c 'export -p | grep HOME='
declare -x HOME="/home/ek"
$ bash -c 'POSIXLY_CORRECT= export -p | grep HOME='
export HOME="/home/ek"
$ bash -c 'set -o posix; export -p | grep HOME='
export HOME="/home/ek"
$ bash --posix -c 'export -p | grep HOME='
export HOME="/home/ek"
$ ln -s /bin/bash sh
$ ./sh -c 'export -p | grep HOME='  # Invoking bash as sh also puts it in POSIX mode.
export HOME="/home/ek"

Zsh показывает нестандартный формат, даже когда включена совместимость с POSIX:

$ zsh -c 'export -p | grep HOME='
typeset -x HOME=/home/ek
$ zsh -c 'emulate -R sh; export -p | grep HOME='
typeset -x HOME=/home/ek
$ ln -s /bin/zsh sh
$ ./sh -c 'export -p | grep HOME='
typeset -x HOME=/home/ek

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

% export -p | grep -oE '\w+=.*'
HOME=/home/ek
LANG=en_US.UTF-8
LESSCLOSE='/usr/bin/lesspipe %s %s'
....

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

Большая часть времени, вы просто хотите , чтобы проверить производительность и поэтому вы не будете заботиться , если запись предшествуют export, declare -x, typeset -xили что - то другое. Тогда просто беги export -p.

Я тестировал эти команды в Ubuntu 16.04 LTS с официально упакованными версиями каждой оболочки.

Элия ​​Каган
источник
0

Переменные, которые НЕ экспортируются, можно увидеть из вывода declareкоманды в bash.

Переменные, которые экспортируются, можно увидеть в выводе команды declare -xили exportв bash.

S471
источник