проблема переменной среды в оболочке

1

Я использую Red Hat Linux Enterprise 5. Я знаю теорию, что при использовании экспорта для задания переменной среды переменная среды будет применяться к текущей и дочерней среде, но без использования экспорта для установки переменной среды переменная среды будет применяться только к текущая среда.

Моя путаница заключается в том, каково точное определение «детской среды» и «текущей среды»? Например,

$ var1=123
$ echo "Hello [$var1]"

значение var1 (которое равно 123) выводится в оболочке, но я думаю, что echo - это команда, вызываемая текущей оболочкой, и она (команда echo) должна быть дочерней средой текущей оболочки, а значение var1 не должно (потому что не используется экспорт var1 = 123) влияние эха. Любые комментарии?

Заранее спасибо!

George2
источник

Ответы:

3

Переменная раскрывается в текущей среде.

$ set -x    # turn on tracing
$ var1=123
+ var1=123
$ echo "Hello [$var1]"
+ echo 'Hello [123]'
Hello [123]
$ set +x

Как вы можете видеть из трассы (строки, начинающиеся с «+»), echoвидит «Hello [123]». Он никогда не получает переменную.

Как вы увидели из ответа Гогеля на ваш другой вопрос, экспортированные переменные окружения влияют на окружение ребенка:

$ echo $LANG
en_US.UTF-8
$ declare -p LANG   # the response includes "-x" which shows the variable is already marked for export
declare -x LANG="en_US.UTF-8"
$ ls --help | head -n 4
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort.
$ LANG=es_MX.utf8 ls --help | head -n 4
Uso: ls [OPCIÓN]... [FICHERO]...
Muestra información acerca de los ARCHIVOS (del directorio actual por defecto).
Ordena las entradas alfabéticamente si no se especifica ninguna de las opciones -cftuSUX ni --sort.

Или я мог бы установить значение LANGв текущей среде, и, поскольку оно экспортируется, оно будет унаследовано дочерней средой:

$ LANG=es_MX.utf8
$ grep --help | head -n 4
Modo de empleo: grep [OPCIÓN]... PATRÓN [FICHERO]...
Busca un PATRÓN en algún ARCHIVO o entrada estándar.
PATTERN es, por omisión, una expresión regular básica (BRE).
Ejemplo: grep -i '¡Hola, mundo!' menu.h main.c
$ sed --help | head -n 4
Uso: sed [OPCIÓN]... {guión-sólo-si-no-hay-otro-guión} [fichero-entrada]...

  -n, --quiet, --silent
                 suprime la muestra automática del espacio de patrones
$ while [[ = 4 ]]    # create an error on purpose to show Spanish error message
bash: se esperaba un operador binario condicional
bash: error sintáctico cerca de `4'

Редактировать:

Вот простой скрипт (давайте назовем его showvars), чтобы вы могли видеть, что происходит как внутри, так и снаружи.

#!/bin/bash
arguments="$@"
printf "The script has started.\n"
printf "These are the parameters passed to the script: [$arguments]\n"
scriptvar=100
printf "This is the value of scriptvar: [$scriptvar]\n"
printf "This is the value of exportvar: [$exportvar]\n"
printf "This is the value of shellvar: [$shellvar]\n"
printf "This is the value of commandvar: [$commandvar]\n"
printf "The script has ended.\n"

Теперь мы делаем эти шаги в командной строке:

$ shellvar=200
$ export exportvar=300
$ ./showvars 400 $shellvar 500
The script has started.
These are the parameters passed to the script: [400 200 500]
This is the value of scriptvar: [100]
This is the value of exportvar: [300]
This is the value of shellvar: []
This is the value of commandvar: []
The script has ended.
$ commandvar=600 ./showvars 400 $shellvar 500
The script has started.
These are the parameters passed to the script: [400 200 500]
This is the value of scriptvar: [100]
This is the value of exportvar: [300]
This is the value of shellvar: []
This is the value of commandvar: [600]
The script has ended.
$ printf "This is the value of commandvar: [$commandvar]\n"
This is the value of commandvar: []
$ commandvar=600
$ ./showvars 400 $shellvar 500
The script has started.
These are the parameters passed to the script: [400 200 500]
This is the value of scriptvar: [100]
This is the value of exportvar: [300]
This is the value of shellvar: []
This is the value of commandvar: []
The script has ended.
$ printf "This is the value of scriptvar: [$scriptvar]\n"
This is the value of scriptvar: []
$ printf "This is the value of exportvar: [$exportvar]\n"
This is the value of exportvar: [300]
$ printf "This is the value of shellvar: [$shellvar]\n"
This is the value of shellvar: [200]
$ printf "This is the value of commandvar: [$commandvar]\n"
This is the value of commandvar: [600]

Как вы можете видеть, shellvarон недоступен внутри скрипта и scriptvarне доступен за его пределами. Поскольку exportvarэкспортируется, он доступен как внутри, так и за пределами сценария. И commandvarдоступен только внутри скрипта, когда он передается в командной строке при вызове скрипта. Если он установлен в интерактивной среде, а затем вызывается сценарий, он доступен только в интерактивной среде.

Деннис Уильямсон
источник
1
Да, переменная раскрывается оболочкой (она заменяет переменную на ее значение), и значение передается echo. Поэтому echoникогда не видит переменную, только ее значение.
Деннис Уильямсон
1
@ George2: Посмотрите на след в верхней части моего ответа. «$» - это приглашение оболочки. Я печатаю, echo "Hello [$var1]"и следующая строка (которая начинается с «+») показывает, что на самом деле происходит. Оболочка (Bash) говорит echoвыводить «123». Оболочка заменяет имя переменной на ее значение до того, как оно ему передается, echoпоэтому echoникогда не видит переменную, а видит только значение, переданное в качестве параметра. Я собираюсь добавить небольшой сценарий к моему ответу, который покажет, что происходит, позволяя вам увидеть внутри процесса. Это займет у меня несколько минут, так что вернитесь, если это еще не сделано.
Деннис Уильямсон
1
@ George2: Какие еще лица? mkdirявляется потомком любой среды, из которой он вызывается - например, интерактивной оболочки или скрипта. Обычно на такие исполняемые файлы влияют только экспортированные переменные среды, которые задокументированы на их manстраницах. Единственный тип переменной среды, который часто эффективен, даже если он не задокументирован на отдельных manстраницах, - это набор переменных, связанных с локалью, как LANGпоказано в некоторых из приведенных выше примеров.
Деннис Уильямсон
1
исполняемые файлы, скрипты, команды, да.
Деннис Уильямсон
1
Нет, не исключение. Посмотрите на file="/etc/passwd"; ls -l "$file"Вот lsполучает значение переменной из родительской оболочки. Значение не сама переменная .
Деннис Уильямсон