vấn đề biến môi trường trong shell


1

Tôi đang sử dụng Red Hat Linux Enterprise 5. Tôi biết lý thuyết rằng - sử dụng xuất để đặt biến môi trường, biến môi trường sẽ áp dụng cho môi trường hiện tại và môi trường con, nhưng không sử dụng xuất để đặt biến môi trường, biến môi trường sẽ chỉ áp dụng cho môi trường hiện tại.

Sự nhầm lẫn của tôi là, định nghĩa chính xác của "môi trường trẻ em" và "môi trường hiện tại" là gì? Ví dụ,

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

giá trị của var1 (là 123) được in bằng shell, nhưng tôi nghĩ echo là lệnh được gọi bởi shell hiện tại và nó (lệnh echo) phải là môi trường con của shell hiện tại và giá trị của var1 không nên (vì không sử dụng xuất var1 = 123) tiếng vang tác động. Có ý kiến ​​gì không?

Cảm ơn trước!

Câu trả lời:


3

Biến được mở rộng trong môi trường hiện tại.

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

Như bạn có thể thấy từ dấu vết (các dòng bắt đầu bằng "+"), echo thấy "Xin chào [123]". Nó không bao giờ có được các biến.

Như bạn đã thấy từ gogiel câu trả lời với câu hỏi khác của bạn, các biến môi trường xuất khẩu có ảnh hưởng đến môi trường của trẻ không:

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

Hoặc tôi có thể đặt giá trị của LANG trong môi trường hiện tại và vì nó được xuất khẩu nên nó sẽ được kế thừa bởi môi trường con:

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

Chỉnh sửa:

Đây là một kịch bản đơn giản (hãy gọi nó là showvars ) để bạn có thể thấy những gì đang diễn ra cả bên trong và bên ngoài.

#!/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"

Bây giờ chúng tôi thực hiện các bước này tại dấu nhắc 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]

Bạn có thể thấy shellvar không có sẵn trong tập lệnh và scriptvar không có sẵn bên ngoài nó. Kể từ khi exportvar được xuất, nó có sẵn cả bên trong và bên ngoài tập lệnh. Và commandvar chỉ khả dụng bên trong tập lệnh khi nó được truyền vào dòng lệnh khi gọi tập lệnh. Nếu nó được đặt trong môi trường tương tác và sau đó tập lệnh được gọi, nó chỉ khả dụng trong môi trường tương tác.


1
Có, biến được mở rộng bởi shell (nó thay thế biến bằng giá trị của nó) và giá trị được truyền vào echo. Vì thế echo không bao giờ nhìn thấy biến, chỉ là giá trị của nó.
Dennis Williamson

1
@ George2: Nhìn vào dấu vết ở đầu câu trả lời của tôi. "$" Là dấu nhắc shell. Tôi gõ echo "Hello [$var1]" và dòng tiếp theo (bắt đầu bằng "+") hiển thị những gì thực sự xảy ra. Cái vỏ (Bash) kể echo để xuất "123". Shell thay thế tên của biến bằng giá trị của nó trước nó đưa nó cho echo vì thế echo không bao giờ thấy biến nó chỉ thấy giá trị thông qua như một tham số. Tôi sẽ thêm một kịch bản nhỏ vào câu trả lời của mình để cho thấy những gì đang diễn ra bằng cách cho bạn thấy bên trong quy trình. Tôi sẽ mất vài phút, vì vậy hãy kiểm tra lại nếu nó chưa ở đó.
Dennis Williamson

1
@ George2: Những loại thực thể khác? mkdir là một đứa trẻ của bất kỳ môi trường nào mà nó được gọi từ - ví dụ như vỏ tương tác hoặc tập lệnh. Thông thường các tệp thực thi như vậy chỉ bị ảnh hưởng bởi các biến môi trường xuất khẩu được ghi lại trong man trang. Một loại biến môi trường thường có hiệu quả mặc dù nó không được ghi lại trong từng cá nhân man trang là tập hợp các biến liên quan đến miền địa phương, chẳng hạn như LANG thể hiện trong một số ví dụ trên.
Dennis Williamson

1
thực thi, kịch bản, lệnh, có.
Dennis Williamson

1
Không, không phải là một ngoại lệ. Nhìn vào file="/etc/passwd"; ls -l "$file" Đây ls đang nhận được một giá trị của biến từ shell cha. Các giá trị không phải chính biến .
Dennis Williamson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.