จะแสดงค่าปัจจุบันของตัวแปรสภาพแวดล้อมได้อย่างไร


24

เมื่อฉันตรวจสอบสภาพแวดล้อมของระบบตัวแปรสภาพแวดล้อมจำนวนมากจะปรากฏขึ้น ฉันจะค้นหาตัวแปรเฉพาะได้อย่างไร

หนังสือที่ฉันกำลังอ่านพูดว่า:

บางครั้งจำนวนของตัวแปรในสภาพแวดล้อมของคุณมีขนาดใหญ่ขึ้นมากจนคุณไม่ต้องการเห็นค่าทั้งหมดที่ปรากฏเมื่อคุณสนใจเพียงตัวเดียว หากเป็นกรณีนี้คุณสามารถใช้echoคำสั่งเพื่อแสดงค่าปัจจุบันของตัวแปรสภาพแวดล้อม

ฉันจะทำสิ่งนี้ใน terminal Linux ได้อย่างไร

คำตอบ:


25

เพียงแค่:

echo "$VARIABLENAME"

ตัวอย่างเช่นสำหรับตัวแปรสภาพแวดล้อม$HOMEให้ใช้:

echo "$HOME"

ซึ่งพิมพ์สิ่งที่คล้ายกับ:

/home/username

แก้ไข : ตามความคิดเห็นของStéphane Chazelasมันอาจจะดีกว่าถ้าคุณใช้printenvแทนecho:

printenv HOME

4
คุณลืมเครื่องหมายคำพูด (เว้นแต่ว่าคุณหมายถึงไวยากรณ์ zsh หรือ rc / es) echoเป็นตัวเลือกที่ไม่ดีของคำสั่งเนื่องจากสามารถแปลงเนื้อหาของตัวแปรได้ มันจะส่งออกเนื้อหาของพารามิเตอร์เปลือกด้วยชื่อเดียวกัน นั่นคือไม่จำเป็นต้องเหมือนกันถ้าใช้บอร์นเปลือกหรือ env vars เช่น1, *ตัวอย่างเช่น และคุณไม่สามารถใช้วิธีการนั้นสำหรับ env vars ที่ชื่อไม่ถูกต้องเป็นชื่อตัวแปรเชลล์
Stéphane Chazelas

5
นอกจากนี้โปรดทราบว่าหากมีรายการสภาพแวดล้อมหลายรายการที่มีชื่อเดียวกัน (ตกลงกรณีทางพยาธิวิทยา) ซึ่งรายการหนึ่งที่คุณจะได้รับขึ้นอยู่กับเชลล์ (โดยปกติจะเป็นรายการแรกหรือรายการสุดท้าย) printenv VARจะแสดงทั้งหมด (อย่างน้อยสำหรับการนำ GNU ไปใช้)
Stéphane Chazelas

9

โดยการดำเนินการ:

printenv

คุณจะเห็นตัวแปรสภาพแวดล้อมทั้งหมด สำหรับข้อมูลเพิ่มเติมคุณสามารถดู:

https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux-vps


2
หากต้องการเข้าใกล้การตอบคำถามจริงๆprintenv variablenameจะแสดงเฉพาะตัวแปรที่ตั้งชื่อ เช่นจะทำประมาณสิ่งเดียวกับprintenv  HOME echo  "$HOME"
G-Man กล่าวว่า 'Reinstate Monica'

5

สิ่งสำคัญคือต้องเข้าใจว่าทุกกระบวนการมีชุดตัวแปรสภาพแวดล้อมของตัวเอง

เมื่อกระบวนการเรียกการเรียกของfork()ระบบกระบวนการที่สอง ( ลูก ) เหมือนกันเป็นครั้งแรก ( แม่ ) ถูกสร้างขึ้น ( สำเนานี้รวมถึงสภาพแวดล้อมซึ่งอยู่เหนือกอง (หรือด้านล่างขึ้นอยู่กับวิธีที่คุณคิดว่าสแต็ค:-)-) แต่ใน Unix / Linux สแต็คที่เติบโตลดลงจากที่อยู่สูง)

โดยปกติแล้วกระบวนการลูกจะเรียกการเรียกของexecve()ระบบซึ่งจะทิ้งทุกอย่างในหน่วยความจำ (เสมือน) และสร้างใหม่จากรหัสและส่วนข้อมูลในไฟล์ไบนารีที่ระบุ

แต่เมื่อมันreconstructsกองสำเนาสภาพแวดล้อมและการโต้แย้งสตริงส่งผ่านไปexecve()บนสแต็คเป็นครั้งแรก (ตามลำดับ) ก่อนการเรียกmain()ฟังก์ชั่น (จำนวนมากของการทำงานจะทำในcrt0รหัสบูตหลังจากที่execve()ผลตอบแทน (ไปยังรายการ จุดที่ระบุไว้ในไบนารี))

มีห่อสำหรับที่มีexecve()การเรียกระบบในห้องสมุด C ที่จะผ่านสภาพแวดล้อมในปัจจุบัน (เช่นคัดลอกของสภาพแวดล้อมของผู้ปกครอง) แทนของผู้โทรให้มัน (เพื่อให้มีผลบังคับใช้เด็กจะได้รับมรดกของสภาพแวดล้อมของผู้ปกครอง) - environ(7)ดู

ลองใช้คำสั่ง (เป็น root) ps axeww | less... ซึ่งจะแสดงสภาพแวดล้อมสำหรับกระบวนการทั้งหมด ! สิ่งที่น่าสนใจคือ id ของกระบวนการ 1 (เช่นinitกระบวนการ - กระบวนการแรกที่สร้างโดยเคอร์เนลในเวลาบูต)

หากคุณต้องการดูสภาพแวดล้อมของกระบวนการเฉพาะ (และคุณรู้ว่าเป็นรหัสกระบวนการ) ให้ลองเรียกใช้คำสั่งcat /proc/<PID>/environ(แทนที่<PID>ด้วยรหัสกระบวนการ)

โปรดทราบว่าหากโปรเซสมีสิทธิ์เพียงพอก็สามารถเขียนสแต็คของตัวเองใหม่ซึ่งทำให้ยากที่จะรู้ว่าสภาพแวดล้อมคืออะไร - คุณจะเห็นกระบวนการ daemon บางอย่างเช่นนี้ในเอาต์พุต ps

แต่ในท้ายที่สุดวาฟเฟิลทั้งหมดจะเดือดร้อนถึงสิ่งที่ @chaos กล่าวไว้ข้างต้นหากคุณต้องการดูค่าปัจจุบันของตัวแปรสภาพแวดล้อมที่เฉพาะเจาะจงในกระบวนการเชลล์ของคุณเพียงใช้คำสั่งecho "$<NAME>"( builtin) (แทนที่<NAME>ด้วยชื่อของ ตัวแปรสภาพแวดล้อมที่คุณสนใจ) ... โปรดทราบว่าตัวแปรเดียวกันอาจมีค่าแตกต่างกันหรือไม่มีเลยในกระบวนการอื่น


1
(1) โปรดทราบว่าeตัวเลือกpsและ/proc/…/environไฟล์พิเศษอาจไม่มีอยู่ในทุกระบบ (2) AFAIK ทุกกระบวนการของ Unix มีสิทธิ์ในการเขียนสแต็กใหม่และแก้ไขตัวแปรสภาพแวดล้อม (3) สำหรับการสนทนาเพิ่มเติมดูที่ตัวแปรสภาพแวดล้อมเป็นของใคร (สำหรับผู้ใช้ระดับสูง )
G-Man กล่าวว่า 'Reinstate Monica'

ฉันมีในหัวของฉันว่าบางระบบมีวิธีในการป้องกันกระบวนการที่ไม่มีผู้ด้อยโอกาสจาก "ซ่อน" อาร์กิวเมนต์บรรทัดคำสั่งและสภาพแวดล้อมเช่นจากการทำงานของรูทps... แต่ตอนนี้คุณได้เน้นจุดนี้แล้วฉันจำไม่ได้ว่าทำไม คิดว่า
Murray Jensen

@MurrayJensen ตามการอภิปรายคำถามที่โหวตอย่างสูงที่ฉันถามเกี่ยวกับ "curl" ซ่อนอาร์กิวเมนต์ของมันใน ps - มันไม่ได้ระบุใน POSIX ว่า ps คืน args ตามที่ส่งผ่านไปยังกระบวนการหรือคัดลอกซึ่งกระบวนการอาจแก้ไขหลังจากนั้น เริ่ม. ระบบบางระบบ (ฉันคิดว่า Solaris ??) แสดงส่วนที่เป็นต้นฉบับไม่ว่าจะเกิดอะไรขึ้น (นี่คือลิงค์) นี่อาจเป็นสิ่งที่คุณคิด :)
ไวด์การ์ด

บิงโก! ใช่แน่นอน Solaris ทำสิ่งนี้ "ถูกต้อง" :-) ขอบคุณสำหรับการทบทวน ...
Murray Jensen

1

คุณสามารถได้รับสิ่งที่คุณกำลังมองหาด้วยexport:

export | grep HOME

จะแสดงเนื้อหาของ$HOMEตัวแปร


1

หากคุณต้องตั้งค่า vars จำนวนมาก:

  ( set -o posix ; set ) | sort >~/vars.before

หลังจากตั้งค่าพวกเขาแล้ว:

  ( set -o posix ; set ) | sort >~/vars.after

กว่าแสดงสิ่งที่ตั้ง:

  comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'

วิธีนี้คุณจะพบว่าตัวคุณเองในไม่ช้าการทำงานกับ shell vars หลายชุดที่กำหนดไว้ล่วงหน้าในไฟล์ cnf ซึ่งรวมกับ tmux จะทำให้คุณเป็นเจ้านายของการจัดการการกำหนดค่าในสภาพแวดล้อมของเชลล์:

  # ---------------------------------------------------------
  # cat cnf/qto.dev.host-name.cnf
  # [MainSection]
  # postgres_db_name     = dev_qto
  # postgres_db_host     = host-name
  #
  # call by: doParseCnfEnvVars cnf/qto.dev.host-name.cnf
  # ---------------------------------------------------------
  doParseCnfEnvVars(){

     cnf_file=$1;shift 1;
     test -z "$cnf_file" && echo " you should set the cnf_file !!!"

     INI_SECTION=MainSection

     ( set -o posix ; set ) | sort >~/vars.before

     eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
        -e 's/#.*$//' \
        -e 's/[[:space:]]*$//' \
        -e 's/^[[:space:]]*//' \
        -e "s/^\(.*\)=\([^\"']*\)$/export \1=\"\2\"/" \
        < $cnf_file \
        | sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^#].*\=.*/p;}"`

     # and post-register for nice logging
     ( set -o posix ; set ) | sort >~/vars.after

     echo "INFO added the following vars from section: [$INI_SECTION]"
     comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'
  }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.