ปัญหาตัวแปรสภาพแวดล้อมในเชลล์


1

ฉันใช้ Red Hat Linux Enterprise 5 ฉันรู้ทฤษฎีว่า - การใช้การส่งออกเพื่อตั้งค่าตัวแปรสภาพแวดล้อมตัวแปรสภาพแวดล้อมจะใช้กับสภาพแวดล้อมปัจจุบันและเด็ก แต่ไม่ใช้การส่งออกเพื่อตั้งค่าตัวแปรสภาพแวดล้อมตัวแปรสภาพแวดล้อมจะใช้กับ สภาพแวดล้อมปัจจุบัน

ความสับสนของฉันคืออะไรคำจำกัดความที่แน่นอนของ "สภาพแวดล้อมของเด็ก" และ "สภาพแวดล้อมปัจจุบัน" คืออะไร? ตัวอย่างเช่น,

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

ค่าของ var1 (ซึ่งคือ 123) ถูกพิมพ์ในเชลล์ แต่ฉันคิดว่า echo เป็นคำสั่งที่เรียกใช้โดยเชลล์ปัจจุบันและ (คำสั่ง echo) ควรเป็นสภาพแวดล้อมลูกของเชลล์ปัจจุบันและค่าของ var1 ไม่ควร (เพราะ ไม่ได้ใช้ export var1 = 123) echo มีคำแนะนำอะไรมั้ย?

ขอบคุณล่วงหน้า!

คำตอบ:


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 prompt:

$ 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 ไม่เคยเห็นตัวแปรเพียงแค่ค่าของมัน
Dennis Williamson

1
@ George2: ดูร่องรอยที่ด้านบนของคำตอบของฉัน "$" เป็นพรอมต์เชลล์ ฉันพิมพ์ echo "Hello [$var1]" และบรรทัดถัดไป (ที่ขึ้นต้นด้วย "+") จะแสดงสิ่งที่เกิดขึ้นจริง เชลล์ (Bash) บอก echo เพื่อส่งออก "123" เชลล์แทนที่ชื่อของตัวแปรด้วยค่าของมัน ก่อน มันให้มันไป echo ดังนั้น echo ไม่เคยเห็นตัวแปรที่เห็นเท่านั้น ราคา ผ่านเป็นพารามิเตอร์ ฉันจะเพิ่มสคริปต์เล็ก ๆ ลงในคำตอบของฉันที่จะแสดงสิ่งที่เกิดขึ้นโดยให้คุณเห็นในกระบวนการ ฉันจะใช้เวลาสองสามนาทีดังนั้นโปรดกลับมาตรวจสอบอีกครั้งถ้ายังไม่มี
Dennis Williamson

1
@ George2: หน่วยงานอื่น ๆ แบบไหน? mkdir เป็นลูกของสภาพแวดล้อมใด ๆ ก็ตามที่ถูกเรียกใช้ - เชลล์โต้ตอบหรือสคริปต์ตัวอย่างเช่น โดยปกติไฟล์ประมวลผลดังกล่าวจะได้รับผลกระทบจากตัวแปรสภาพแวดล้อมที่ถูกส่งออก man หน้า ตัวแปรสภาพแวดล้อมชนิดหนึ่งที่มักจะมีประสิทธิภาพแม้ว่าจะไม่ได้จัดทำเป็นเอกสารไว้ man pages คือชุดของตัวแปรที่เกี่ยวข้องกับโลแคลเช่น LANG แสดงให้เห็นในตัวอย่างข้างต้น
Dennis Williamson

1
executables, สคริปต์, คำสั่ง, ใช่
Dennis Williamson

1
ไม่ไม่ใช่ข้อยกเว้น ดูที่ file="/etc/passwd"; ls -l "$file" ที่นี่ ls กำลังรับค่าของตัวแปรจากพาเรนต์เชลล์ ราคา ไม่ ตัวแปรนั้นเอง .
Dennis Williamson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.