จะตั้งค่าตัวแปรสภาพแวดล้อมเฉพาะช่วงเวลาของสคริปต์ได้อย่างไร?


127

บน Linux (Ubuntu 11.04) ใน bash เป็นไปได้ไหมที่จะตั้งค่าตัวแปรสภาพแวดล้อมชั่วคราวที่จะแตกต่างจากตัวแปรปกติในช่วงระยะเวลาของสคริปต์? ตัวอย่างเช่นในเชลล์สคริปต์การสร้างแอปที่บันทึกไปยัง HOME แบบพกพาโดยการตั้งค่า HOME เป็นโฟลเดอร์ชั่วคราวในไดเร็กทอรีการทำงานปัจจุบันจากนั้นเปิดแอป


5
มันจะยากกว่าถ้าคุณต้องการให้การตั้งค่าอยู่นานกว่าระยะเวลาของสคริปต์
Nemo

คำตอบ:


120
VAR1=value1 VAR2=value2 myScript args ...

2
vblank_mode=0 glxgearsฉันได้กระทำนี้ตัวเองหลายครั้งหลายคราที่จะวิ่ง มันใช้งานได้ แต่ยังบอกvblank_mode=0: command not foundหลังจากทำงานในขณะที่การเติมเงินล่วงหน้าenvจะไม่ทำให้เกิดสิ่งนี้ [การทดสอบ ... ] เห็นได้ชัดว่า zsh ไม่ชอบมัน (แต่ก็ยังใช้อย่างถูกต้อง) แต่ bash ก็ใช้ได้ ฉันเดาว่าฉันจะใช้envวิธีการต่อจากนี้
Chinoto Vokro

2
ด้วยสคริปต์มันใช้งานได้ แต่ VAR1="hello" echo $VAR1จะไม่ส่งคืนอะไรเลย?
Zibri

2
@ Zibri เป็นเรื่องเกี่ยวกับเมื่อการขยายตัวเกิดขึ้น คุณอาจทำอะไรแบบนั้นได้:VAR1="hello" bash -c 'echo $VAR1'
cybergrind

ได้รับการโหวตให้แสดงว่าสิ่งนี้เป็นไปได้แม้กระทั่งสำหรับตัวแปรสภาพแวดล้อมหลายตัว
Binarus

70
env VAR=value myScript args ...

18
หรือVAR=value myScript args ...
Rockallite

9
1. ทำไมPATH=$PATH:XYZ echo $PATH | grep XYZไม่มีเอาท์พุทเลย? 2. ใช้กับไม่ใช้ต่างกันenvอย่างไร?
qubodup

18
เนื่องจากเชลล์ขยายตัวแปร PATH ก่อนดำเนินการคำสั่ง echo คุณต้องชะลอการขยายนั้น ทางเดียว: PATH=$PATH:XYZ sh -c 'echo $PATH' | grep XYZ- คำพูดเดียวเป็นกุญแจสำคัญที่นี่
Glenn Jackman

14
ใช้envกับไม่ใช้ต่างกันอย่างไร?
Mohammed Noureldin

สิ่งนี้ดูเหมือนจะไม่ทำงานใน oneliner เช่นIFS=$'\n' for l in lines; do ... done
drevicko

31

เพียงแค่ใส่

export HOME=/blah/whatever

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


11
นั่นทำให้เข้าใจผิด exportจะส่งผ่านตัวแปรไปยัง subshells แต่ไม่ได้ควบคุมพาเรนต์เชลล์ หากคุณกำลังเขียนสคริปต์ที่ขึ้นต้นด้วย "#! / bin / sh" หรือสิ่งที่คล้ายกันตัวแปรใด ๆ ที่คุณตั้งไว้จะหายไปเมื่อสคริปต์ออก
brightlancer

1
@brightlancer นั่นเป็นความจริง แต่ดูเหมือนจะไม่ขัดแย้งกับสิ่งที่ฉันเขียน (ยกเว้นความเป็นไปได้ที่สคริปต์อาจเริ่มกระบวนการเบื้องหลัง แต่ฉันคิดว่ามันเกินระดับความซับซ้อนของ OP และจะทำให้สับสนเท่านั้น)
hmakholm ออกจาก Monica

5
การส่งออกนั้นไม่จำเป็น นอกจากนี้คำตอบของคุณจะใช้ได้ก็ต่อเมื่อสคริปต์ของเขาเรียกใช้ล่าม (#! / bin / sh หรือสิ่งที่คล้ายกัน) หาก "สคริปต์" ของเขาไม่เป็นเช่นนั้นสิ่งที่คุณเพิ่งบอกเขาจะคงอยู่ต่อไปจนจบบท นั่นคือเหตุผลที่ฉันบอกว่าคำตอบของคุณทำให้เข้าใจผิด - อาจถูกต้องอาจไม่ใช่ แต่แน่นอนว่ามีส่วนที่ไม่จำเป็นและสับสนเพราะอาจทำให้ใครบางคนคิดว่า "การส่งออก" เป็นองค์ประกอบที่จำเป็นที่เขากำลังมองหา
brightlancer

7
@brightlancer: การส่งออกเป็นสิ่งที่จำเป็นหากสคริปต์ของ OP เรียกใช้สคริปต์ย่อยที่ขึ้นอยู่กับ $ HOME และฉันไม่กล้าคิดว่าไม่ใช่กรณีนี้ นอกจากนี้ bash จะสร้าง subshell เพื่อเรียกใช้สคริปต์แม้ว่าสคริปต์จะไม่มีบรรทัด shebang แต่เป็นเพียงไฟล์ข้อความที่มีชุดบิตดำเนินการ ลองใช้ - การกำหนดตัวแปรในสคริปต์จะไม่ปรากฏในเชลล์ที่คุณเรียกใช้ เฉพาะในกรณีที่คุณระบุsourceสคริปต์อย่างชัดเจนซึ่งจะถูกเรียกใช้โดยเชลล์เดียวกับที่คุณพิมพ์คำสั่ง
hmakholm ออกจาก Monica

4
@brightlancer: การส่งออกเป็นสิ่งที่จำเป็นหากเขาต้องการ$HOMEสืบทอดโดยคำสั่งใด ๆ ที่เรียกใช้จากสคริปต์ และถ้าเขาไม่ได้และการตั้งค่าของเป็นเพียงเพื่อประโยชน์ของสคริปต์ของตัวเองแล้วเขาต้องการอาจจะดีกว่าการปรับเปลี่ยนสคริปต์เพื่อให้มันหมายถึงสิ่งอื่นที่ไม่ใช่$HOME $HOME
Keith Thompson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.