shell中的环境变量问题


1

我正在使用Red Hat Linux Enterprise 5.我知道这样的理论 - 使用export来设置环境变量,环境变量将应用于当前和子环境,但是不使用export来设置环境变量,环境变量将仅适用于当前的环境。

我的困惑是,“儿童环境”和“当前环境”的确切定义是什么?例如,

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

var1(即123)的值是在shell中打印的,但我认为echo是当前shell调用的命令,它(echo命令)应该是当前shell的子环境,而var1的值不应该(因为不使用export var1 = 123)影响echo。任何意见?

提前致谢!

Answers:


3

变量在当前环境中扩展。

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

从迹线(以“+”开头的行)可以看出, echo 看到“你好[123]”。它永远不会得到变量。

如你所见 gogiel的 回答 对于您的其他问题,导出的环境变量确实会影响孩子的环境:

$ 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"

现在我们在shell提示符下执行以下步骤:

$ 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
是的,变量由shell扩展(它将变量替换为其值)并将值传递给 echo。所以 echo 永远不会看到变量,只看它的价值。
Dennis Williamson

1
@ George2:看看我答案顶部的痕迹。 “$”是shell提示符。我打字 echo "Hello [$var1]" 并且下一行(以“+”开头)显示实际发生的情况。 shell(Bash)告诉我 echo 输出“123”。 shell用其值替换变量的名称 之前 它给了它 echo 所以 echo 永远不会看到它只看到的变量 作为参数传递。我将在我的回答中添加一个小脚本,通过让您看到流程内部来显示正在发生的事情。这将需要几分钟,所以请检查它是否还没有。
Dennis Williamson

1
@ George2:什么样的其他实体? mkdir 是一个孩子,无论从哪个环境调用它 - 例如交互式shell或脚本。通常,此类可执行文件仅受其中记录的导出环境变量的影响 man 页面。一种类型的环境变量,即使没有在个人中记录,也经常有效 man pages是一组与语言环境相关的变量,例如 LANG 在上面的一些例子中证明了这一点。
Dennis Williamson

1
可执行文件,脚本,命令,是的。
Dennis Williamson

1
不,不是例外。看着 file="/etc/passwd"; ls -l "$file" 这里 ls 从父shell接收变量的值。该 变量本身
Dennis Williamson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.