ส่งออกตัวแปร env เพื่อให้พร้อมใช้งานที่เชลล์ย่อยทั้งหมดและสามารถแก้ไขได้หรือไม่


22

สมมติว่าฉันมี

export MY_VAR=0

ใน~/.bashrc.

ฉันมีขั้วคำพังเพยเปิดและในสถานีนี้เปลี่ยนแปลงฉันมูลค่าให้กับ$MY_VAR 200ดังนั้นถ้าฉันทำ

echo $MY_VAR

ในสถานีนี้200จะปรากฏขึ้น

ตอนนี้ฉันเปิดแท็บอื่นในเทอร์มินอล gnome และทำ

echo $MY_VAR

... และแทนผมมี2000

ฉันควรทำอย่างไรเพื่อยืนยันค่า 200 เมื่อเทอร์มินัลแก้ไขตัวแปรสภาพแวดล้อมทำให้การแก้ไขนี้ (การตั้งค่าเป็น 200) พร้อมใช้งานสำหรับเชลล์ย่อยที่ตามมาทั้งหมดและเช่นนั้น? เป็นไปได้ไหม

คำตอบ:


23

สำเนาของแพร่กระจายสภาพแวดล้อมในการย่อยเปลือกหอยเพื่อให้งานนี้:

$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200

แต่เนื่องจากเป็นสำเนาคุณจึงไม่สามารถรับค่านั้นได้สูงสุดถึง parent shell - ไม่ใช่โดยการเปลี่ยนสภาพแวดล้อมอย่างน้อยที่สุด

ดูเหมือนว่าคุณต้องการที่จะก้าวไปอีกขั้นซึ่งจะทำให้บางสิ่งบางอย่างที่ทำหน้าที่เหมือนตัวแปรทั่วโลกใช้ร่วมกันโดยเชลล์ "sibling" ที่เริ่มต้นแยกจากผู้ปกครองเช่นแท็บใหม่ใน Gnome Terminal

ส่วนใหญ่คำตอบคือ "คุณทำไม่ได้เพราะตัวแปรสภาพแวดล้อมใช้ไม่ได้" อย่างไรก็ตามมีคำตอบอีกข้อหนึ่งซึ่งก็คือคุณสามารถแฮ็กข้อมูลได้เสมอ วิธีหนึ่งคือการเขียนค่าของตัวแปรไปยังไฟล์เช่น~/.myvarจากนั้นรวมสิ่งนั้นเข้า~/.bashrcด้วยกัน จากนั้นแต่ละเชลล์ใหม่จะเริ่มต้นด้วยค่าที่อ่านจากไฟล์นั้น

คุณสามารถไปอีกขั้น - ทำ~/.myvarในรูปแบบMYVAR=200แล้วกำหนดPROMPT_COMMAND=source ~/.myvarซึ่งจะทำให้ค่าที่จะอ่านอีกครั้งทุกครั้งที่คุณได้รับพรอมต์ใหม่ ก็ยังคงไม่ได้ค่อนข้างตัวแปรส่วนกลางที่ใช้ร่วมกัน แต่มันก็เริ่มที่จะกระทำเช่นนั้น มันจะไม่เปิดใช้งานจนกว่าจะมีข้อความแจ้งกลับมาซึ่งขึ้นอยู่กับสิ่งที่คุณพยายามทำอาจเป็นข้อ จำกัด ที่ร้ายแรง

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


10
ฉันได้ยินเสียงเปลือกเปิดเผยภายใต้การทรมาน

ใช่ขอโทษ นั่นเป็นเหตุผลที่ฉันหยุด :)
mattdm

"ซึ่งจะทำให้บางสิ่งบางอย่างที่ทำหน้าที่เหมือนตัวแปรทั่วโลก" - จริง ๆ แล้วนั่นคือสิ่งที่ฉันพยายามทำให้เข้าใจ ~ / .myvar ไม่สวย แต่ใช้งานได้ คุณมีข้อเสนอแนะอื่นหรือไม่?
บางคนยังใช้ MS-DOS ของคุณ

2
งั้นลองย้อนกลับไปสักหน่อย ทำไมคุณถึงต้องการตัวแปรทั่วโลก?
mattdm

1
@mattdm: ฉันมี "ข้าราชการ" ที่ฉันต้องเชื่อฟัง หนึ่งในนั้นคือรหัสที่ฉันต้องใช้ในการคอมเม้นท์ ตอนนี้รหัสเหล่านี้อยู่ในลำดับชั้นของโฟลเดอร์ (home / user / project / projectcode / code1 / code2) ฉันทำฟังก์ชั่นที่ดึง code1 และ code2 ไปที่ env vars (ดังนั้นเมื่อฉันต้องการทำกิจกรรมฉันแค่เรียกฟังก์ชั่นภายใน dir ด้วยรหัส) และพวกเขาเมื่อคอมมิชชันฉันใช้ vim และมีบางฟังก์ชันที่ อ่าน vars เหล่านี้และใส่ความคิดเห็นโดยอัตโนมัติ ฉันคิดว่าการใช้ไฟล์เพื่อเป็นทางออก
บางคนยังใช้ MS-DOS ของคุณ

13

สมมติว่าฉันมีในexport MY_VAR=0~/.bashrc

นั่นคือความผิดพลาดของคุณที่นั่น คุณควรกำหนดตัวแปรสภาพแวดล้อมของคุณ~/.profileซึ่งจะถูกอ่านเมื่อคุณเข้าสู่ระบบ~/.bashrcจะอ่านทุกครั้งที่คุณเริ่มเชลล์ MY_VARเมื่อคุณเริ่มต้นเปลือกมันแทนที่ หากคุณไม่ได้ทำเช่นนั้นตัวแปรสภาพแวดล้อมของคุณจะเผยแพร่ลง

สำหรับข้อมูลเพิ่มเติมเกี่ยว~/.bashrcVS ~/.profileดูของฉันก่อนหน้านี้ โพสต์ บน นี้ หัวข้อ

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



3

อย่าใช้ตัวแปรสภาพแวดล้อมเลย ใช้ไฟล์

เพื่อป้องกันไม่ให้กระบวนการเหยียบกันเมื่ออัปเดต / อ่านไฟล์ให้ใช้ lockfiles และสคริปต์ตัวอัปเดต front-end ขนาดเล็กซึ่งมีวัตถุประสงค์เพียงแค่อัปเดตไฟล์ด้วย $ 1 หากไม่ถูกล็อก Lockfiles มีการใช้งานโดยการตรวจสอบว่ามีไฟล์เฉพาะอยู่ (/var/run/yourscript.lck) หรือไม่และรอให้ไฟล์นั้นหายไปครู่หนึ่งและล้มเหลวหากไม่มี นอกจากนี้คุณต้องลบ lockfile เมื่อทำการอัพเดตไฟล์เสร็จแล้ว

เตรียมรับมือกับสถานการณ์ที่สคริปต์ไม่สามารถอัปเดตไฟล์ได้เนื่องจากไฟล์ไม่ว่าง


8
เคล็ดลับ: ใช้ไดเรกทอรีแทนไฟล์สำหรับล็อคเพราะmkdirทำงานเป็นอะตอมมิกทดสอบและสร้าง
mattdm

1
หากพวกคุณต้องการพูดคุยเกี่ยวกับการล็อคคุณก็อาจจะใช้เช่นกันflock(2)
Ehtesh Choudhury

@mattdm ฉันพบว่า symlink ln -s dummy lockfile(แม้ว่าจะใช้งานไม่ได้) อาจทำงานได้เช่นกันเพราะจะล้มเหลวหาก symlink มีอยู่แล้ว ฉันสงสัยวิธีทดสอบว่าปลอดภัยอย่างแท้จริง 100% หรือไม่
กุมภ์กุมภ์

1

เมื่อฉันเพิ่ง googled คำถามนี้ขึ้นฉันพยายามที่จะแก้ปัญหาของการปรับปรุงสถานะ (เช่นตัวแปรเปลือก) จากนอก subshells เพื่อให้ใครสามารถกำหนดตัวแปรพูดภายในของไปป์ไลน์และการมอบหมายจะปรากฏให้ผู้ปกครองเห็นอย่างโปร่งใส

นอกหลักสูตรนี้เป็นไปไม่ได้ในวิธีที่ง่ายเพราะแต่ละส่วนของไปป์ไลน์จะถูกดำเนินการใน subshells ซึ่งเป็นfork'ed จาก parent shell ดังนั้นจึงมีหน่วยความจำซึ่งเป็นมุมมองcopy-on-writeในหน่วยความจำของพาเรนต์ แต่ผมคิดว่าวิธีการแก้ปัญหาที่บางและโปร่งใสจะเป็นไปได้บนพื้นฐานของ " หน่วยความจำร่วม " การจัดเรียงของIPCs

และฉันก็พบว่ามีการใช้งานการออกแบบนี้อย่างแน่นอน ... แต่มันอยู่ใน Perl

การเพิ่มคำตอบนี้เป็นวิธีแก้ปัญหาที่เป็นไปได้

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