ตัวแปรสภาพแวดล้อมของกระบวนการทำงานบน Unix?


231

ฉันต้องการแก้ไขปัญหาบางอย่างที่เกี่ยวข้องกับตัวแปรสภาพแวดล้อมในระบบ Unix

บน Windows ฉันสามารถใช้เครื่องมือเช่น ProcessExplorer เพื่อเลือกเฉพาะกระบวนการและดูค่าของตัวแปรสภาพแวดล้อมแต่ละตัว

ฉันจะทำสิ่งเดียวกันใน Unix ได้อย่างไร echoingและenvcmd เพียงแสดงค่าในเวลาปัจจุบัน แต่ฉันต้องการดูค่าที่กระบวนการกำลังใช้อยู่ในปัจจุบัน


2
แม้ว่า / proc / <pid> / environ มีขนาดเป็น 0 แต่ยังมีข้อมูลอยู่ในนั้น "มันสมเหตุสมผลกว่าถ้าคุณคิดว่ามันเป็นหน้าต่างเข้าไปในเคอร์เนลไฟล์ไม่ได้มีข้อมูลใด ๆ จริง ๆ มันแค่ทำหน้าที่เป็นตัวชี้ไปยังที่ซึ่งข้อมูลกระบวนการจริงตั้งอยู่" [แหล่งที่มา ]
nevets1219

คำตอบ:


295
cat /proc/<pid>/environ

หากคุณต้องการ pid (s) ของปฏิบัติการที่กำหนดให้คุณสามารถใช้pidof:

AlberT$ pidof sshd   
30690 6512 

แก้ไข :

ฉันอ้างความคิดเห็นของเดนนิสวิลเลียมสันและเท็ดดี้โดยสิ้นเชิงเพื่อให้ได้ผลลัพธ์ที่อ่านง่ายขึ้น โซลูชันของฉันมีดังต่อไปนี้:

tr '\0' '\n' < /proc/<pid>/environ

46
เพื่อให้อ่าน, แปลง nulls เพื่อขึ้นบรรทัดใหม่:cat /proc/17330/environ | tr \\0 \\n
เดนนิสวิลเลียมสัน

32
ฉันมักจะทำxargs --null --max-args=1 echo < /proc/PID/environ
Teddy

7
ดีกว่าใช้สตริงมันเร็ว แมวยังเร็วกว่า :-)
Nikhil Mulley

3
/procระบบไฟล์ทั้งหมดไม่สามารถพกพาได้
Daniel H

6
ผมไม่เข้าใจว่าทำไมการใช้xargsการแปลง nulls trเพื่อขึ้นบรรทัดใหม่จะดีกว่าการใช้ มีใครช่วยฉันได้ไหม ขอบคุณ
Jonathan Hartley

61

เนื่องจากคำถามนี้มีแท็กunixและทุกคนทำเช่นนั้นได้อย่างยอดเยี่ยมในการจัดการกับแท็กlinuxคุณสามารถรับข้อมูลนี้ใน OS X และระบบอื่น ๆ ที่ได้รับจาก BSD

ps -p <PID> -wwwe

หรือ

ps -p <PID> -wwwE

และบน Solaris ด้วย

/usr/ucb/ps -wwwe <PID>

Solaris ยังสนับสนุน/procไดเรกทอรีถ้าคุณไม่ต้องการที่จะจำปิดบังpscommmand


3
II รันps -p <PID> -ww เราบน OS X 10.6 ฉันได้รับรายการกระบวนการที่กำลังทำงานอยู่ทั้งหมด คำสั่งที่ถูกต้องคือพร้อมกับแฟล็ก -Eไม่ใช่ -e
drAlberT

1
ฉันทดสอบบน OS X 10.4 แต่ไม่ใช่ 10.5 อัปเดตตาม
เจอรัลด์รวงผึ้ง

4
มันไม่สมบูรณ์แบบ ตัวเลือก -E รายงานตัวแปรสภาพแวดล้อมเริ่มต้นเท่านั้น หากตัวแปรที่มีการเปลี่ยนแปลงโดยกระบวนการทำงานของตัวเอง (เช่นผ่านการใช้ POSIX putenv () ฟังก์ชั่น) ps -p <PID> -wwEการเปลี่ยนแปลงจะไม่สะท้อนให้เห็นในการส่งออกของ
Kal

1
ไม่เห็นกระบวนการที่ไม่ได้เป็นของคุณฟังดูเหมือนเป็นคุณสมบัติที่พึงประสงค์ นอกจากนี้ยังเป็นกรณีสำหรับคำตอบของลินุกซ์ที่มุ่งเน้นของ @ drAlberT /proc/PID/environใช้ ไฟล์เหล่านั้นสามารถอ่านได้โดยเจ้าของกระบวนการเท่านั้น
Jonathan Hartley

1
@yani เป็นไปได้ แต่มันยากขึ้นมากโดยต้องแนบตัวดีบักกับกระบวนการที่กำลังรันอยู่ ดูคำตอบนี้: unix.stackexchange.com/a/70636
Kal

25

ดังที่คนอื่น ๆ พูดถึงบน Linux คุณสามารถดูใน / proc แต่มีขึ้นอยู่กับรุ่นเคอร์เนลของคุณขีด จำกัด หนึ่งหรือสอง:

ก่อนอื่นไฟล์ environ จะมีสภาพแวดล้อมตามที่ดูเมื่อกระบวนการเกิดขึ้น นั่นหมายความว่าการเปลี่ยนแปลงใด ๆ ที่กระบวนการทำกับสภาพแวดล้อมจะไม่สามารถมองเห็นได้ใน / proc:

$ cat /proc/$$/environ | wc -c
320
$ bash
$ cat /proc/$$/environ | wc -c
1270
$ 

เชลล์ตัวแรกคือเชลล์ล็อกอินและเริ่มมีสภาพแวดล้อมที่ จำกัด มาก แต่เติบโตโดยการจัดหาเช่น. bashrc แต่ / proc ไม่ได้สะท้อนสิ่งนี้ เชลล์ตัวที่สองสืบทอดสภาพแวดล้อมที่มีขนาดใหญ่กว่าตั้งแต่เริ่มต้นซึ่งเป็นเหตุผลที่แสดงใน / proc

นอกจากนี้สำหรับเมล็ดที่เก่ากว่าเนื้อหาของไฟล์ environ จะถูก จำกัด ไว้ที่ขนาดหน้ากระดาษ (4K):

$ cat /proc/$$/environ | wc -c
4096
$ env | wc -c
10343
$ 

อยู่ระหว่าง 2.6.9 (RHEL4) ถึง 2.6.18 (RHEL5) ขีด จำกัด นี้ถูกลบออก ...


1
เป็นไปได้หรือไม่ที่จะได้รับตัวแปรสภาวะแวดล้อมของกระบวนการรีโมตที่ถูกตั้งค่าหลังจากกระบวนการเกิดขึ้นแล้ว? ฉันเข้าใจว่าใน VFS นั้นจะแสดงด้วย / proc / self / environ แต่ถ้าเราอยู่ในกระบวนการ แต่วิธีการรับนี้สำหรับกระบวนการระยะไกล
GP92

11

การใช้ตัวเลือก BSD อย่างถูกต้องเพื่อทำสิ่งนี้ (อย่างน้อยใน linux):

ps e $pid

หรือ

ps auxe  #for all processes

และใช่ manpage ps ค่อนข้างสับสน ( ผ่าน )


อูบุนตูของฉันทุบตัวแปรสภาพแวดล้อมให้ตรงกับบรรทัดคำสั่งโดยไม่เว้นแม้แต่ช่องว่างระหว่างพวกมันและตัดให้เหลือหนึ่งบรรทัดบนหน้าต่างเทอร์มินัล ฉันพบการps eww $pidแก้ไขปัญหาที่ 2
user18911

1
@ user18911: env vars มีตัวคั่นอักขระ null คำตอบอื่น ๆ ในหน้านี้แสดงวิธีใช้xargsหรือtrแปลงเป็นบรรทัดใหม่เพื่อความสะดวกในการอ่าน คุณอาจรู้เรื่องนี้ในช่วงสี่ปีที่ผ่านมา
Jonathan Hartley

7
cat /proc/PID/environ

แทนที่ PID ด้วย PID ของกระบวนการที่คุณต้องการดู ข้อมูลทุกอย่างเกี่ยวกับกระบวนการทำงานอยู่ภายใต้ / proc / PID / ไดเรกทอรี

ตัวอย่าง: cat / proc / 32512 / environ


7

นำมาจากวิกิ Archlinux :

/proc/<pid>/environคุณสามารถสร้างฟังก์ชั่นชั่วคราวที่จะแยกค่าใน ที่หน้าจอพร้อมรับ:

envof() { sed 's/\x0/\n/g' /proc/${1}/environ; }

จากนั้นด้วย pid ของกระบวนการที่คุณต้องการเพียงใช้:

envof <pid>



5

ในขณะที่เอกสารค่อนข้างกระจัดกระจายเนื้อหาของ/proc/<pid>/environจะมีเพียงสภาพแวดล้อมที่ใช้ในการเริ่มต้นกระบวนการ

gdbหากคุณจำเป็นต้องตรวจสอบสถานะปัจจุบันของกระบวนการสิ่งแวดล้อมวิธีหนึ่งที่จะทำคือการใช้

# Start gdb by attaching it to a pid or core file
gdb <executable-file> <pid or core file>

# Run the following script to dump the environment
set variable $foo = (char **) environ
set $i = 0
while ($foo[$i] != 0)
print $foo[$i++]
end

3

และเนื่องจากงานของฉันทำให้ฉันเป็นแฟนบอยของ AIX อย่าลืม:

ps eww [pid]

หรืออย่างที่คนเรียกมันว่า "มาตรฐานของเบิร์กลีย์"

ด้วยเหตุผลใดก็ตาม / proc / PID / environ ไม่มีอยู่ใน AIX


2

หากคุณต้องการสร้างรูปแบบenvเช่นผลลัพธ์ของตัวแปรสภาพแวดล้อมสำหรับกระบวนการโดยพลการ (PID) คุณสามารถสร้างpenv <pid>คำสั่งbash ที่สะดวก(ปรับให้เหมาะกับ OS ของคุณ) และเพิ่มลงใน.bashrc:

Linuxเพิ่มสิ่งนี้ใน ~ / .bashrc ของคุณ:

penv () { 
    xargs --null --max-args=1 < /proc/$1/environ
}

macOS / BSDเพิ่มสิ่งนี้ใน ~ / .bashrc ของคุณ:

penv() {
   ps eww -o command $1  | tr ' ' '\n'
}

Solarisเพิ่มลงใน ~ / .bashrc ของคุณ:

penv() {
   pargs -e $1
}

การใช้งาน:

$ source $ HOME / .bashrc
$ pgrep VBoxSVC
10268
$ penv 1,0268
SSH_CONNECTION = 1.1.1.242 53960 1.1.1.91 22
GREP_COLORS = SL = 49; 39: cx = 49; 39: MT = 49; 38; 5; 167; 1: Fn = 49; 39; 1: LN = 49; 39: พันล้าน = 49; 39: SE = 50; 39
LANG = en_US.UTF-8
EDITOR = เป็นกลุ่ม
XDG_SESSION_ID = 106
USER = ราก
PWD = / ราก
หน้าแรก = / ราก
SSH_CLIENT = 1.1.1.242 53960 22
SSH_TTY = / dev / pts / 3
MAIL = / var / mail / ราก
ระยะ = xterm-256color
SHELL = / bin / ทุบตี
SHLVL = 1
LOGNAME = ราก
DBUS_SESSION_BUS_ADDRESS = ยูนิกซ์: เส้นทาง = / วิ่ง / ผู้ใช้ / 0 / รถบัส
XDG_RUNTIME_DIR = / วิ่ง / ผู้ใช้ / 0
PATH = / ราก / bin: / bin: / sbin: / usr / bin: / usr / sbin: / usr / local / bin: / usr / local / sbin :.
VBOX_LOG_FLAGS = thread tsc
VBOX_LOG = พัก + + dev_vmm_backdoor.elf dev_vmm.elf

0

วิธีแก้ปัญหา mac อาจจะเป็น BSD อื่น ๆ ก็ได้เช่นกัน

pid=28369; ps e $pid | cut -c$(expr 1 + $(ps p $pid|tail +2|wc -c))-

ตัวแปรสภาพแวดล้อมถูกผนวกเข้ากับบรรทัดคำสั่งสิ่งนี้จะลบบรรทัดคำสั่งและเราจะเหลือตัวแปรสภาพแวดล้อมเท่านั้น

มันไม่สมบูรณ์แบบเนื่องจากมีการแยกพื้นที่ออกจากกันไม่ใช่แยก LF


-1

/ proc / PID / สภาพแวดล้อม

สำหรับสิ่งนี้ก่อนอื่นเราต้องระบุ PID ของกระบวนการ สำหรับสิ่งนี้คุณสามารถใช้คำสั่ง ps

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.