ฉันสามารถเรียกใช้ENV_VAR=value command
เพื่อให้ทำงานที่มีค่าเฉพาะสำหรับcommand
ENV_VAR
อะไรที่เทียบเท่ากับ unset ENV_VAR
สำหรับcommand
?
cmd
สำหรับการที่
ฉันสามารถเรียกใช้ENV_VAR=value command
เพื่อให้ทำงานที่มีค่าเฉพาะสำหรับcommand
ENV_VAR
อะไรที่เทียบเท่ากับ unset ENV_VAR
สำหรับcommand
?
cmd
สำหรับการที่
คำตอบ:
นอกเหนือจาก-i
ตัวเลือกซึ่งใช้env
ล้างสภาพแวดล้อมทั้งหมด POSIX ไม่มีวิธีการยกเลิกการตั้งค่าตัวแปร
อย่างไรก็ตามด้วยการenv
ใช้งานบางอย่าง(รวมถึง GNU, busybox
'และ FreeBSD เป็นอย่างน้อย) คุณสามารถทำได้:
env -u ENV_VAR command
ซึ่งจะทำงานในการลบทุกอินสแตนซ์ของENV_VAR
ตัวแปรจากสภาพแวดล้อม (โปรดทราบว่ามันไม่ทำงานสำหรับตัวแปรสภาพแวดล้อมที่มีชื่อว่างเปล่า ( env -u ''
อาจให้ข้อผิดพลาดหรือไม่มีประสิทธิภาพขึ้นอยู่กับการนำไปใช้แม้ว่าจะยอมรับทั้งหมดenv '=value'
อาจเป็นข้อ จำกัด ที่เกิดขึ้นจากunsetenv()
ฟังก์ชั่น C ซึ่ง POSIX ต้องการส่งคืนข้อผิดพลาดสำหรับสตริงว่างขณะที่ไม่มีข้อ จำกัด ดังกล่าวputenv()
))
พกพาได้ (ใน POSIX shells) คุณสามารถทำสิ่งต่อไปนี้
(unset -v ENV_VAR; exec command)
(โปรดทราบว่าในบางเชลล์การใช้exec
สามารถเปลี่ยนสิ่งที่command
รันได้: รันหนึ่งในระบบไฟล์แทนฟังก์ชั่นหรือ builtin เช่น (และจะหลีกเลี่ยงalias
การขยายตัวที่เห็นได้ชัด) เช่นenv
ด้านบนคุณต้องการละเว้นในกรณีเหล่านี้) .
แต่นั่นจะไม่ทำงานสำหรับตัวแปรสภาพแวดล้อมที่มีชื่อที่ไม่สามารถแมปกับตัวแปรเชลล์ได้ (โปรดทราบว่าบางเชลล์ที่ชอบmksh
จะตัดตัวแปรเหล่านั้นออกจากสภาพแวดล้อมเมื่อเริ่มต้นอย่างไรก็ตาม) หรือตัวแปรที่ทำเครื่องหมายว่าเป็นแบบอ่านอย่างเดียว
-v
ใช้สำหรับเชลล์เป้าหมายและbash
ผู้ที่unset
ไม่-v
สามารถยกเลิกการตั้งค่าENV_VAR
ฟังก์ชั่นหากไม่มีตัวแปรตามชื่อนั้น เชลล์อื่น ๆ ส่วนใหญ่จะไม่ตั้งค่าฟังก์ชั่นจนกว่าคุณจะผ่าน-f
ตัวเลือก (ไม่น่าจะสร้างความแตกต่างในทางปฏิบัติ)
(นอกจากนี้ระวังข้อผิดพลาด / misfeature ของbash
/ mksh
/ yash
ซึ่งunset
ภายใต้สถานการณ์บางอย่างอาจไม่ล้างค่าตัวแปร แต่เปิดเผยตัวแปรในขอบเขตด้านนอก )
ถ้าperl
มีคุณสามารถทำได้:
perl -e 'delete $ENV{shift@ARGV}; exec @ARGV or die$!' ENV_VAR command
ซึ่งจะทำงานได้แม้กับตัวแปรสภาพแวดล้อมที่มีชื่อว่าง
ตอนนี้สิ่งเหล่านั้นจะไม่ทำงานหากคุณต้องการเปลี่ยนตัวแปรสภาพแวดล้อมสำหรับ builtin หรือฟังก์ชั่นและไม่ต้องการให้พวกเขาทำงานใน subshell เช่นในbash
:
env -u LANG printf -v var %.3f 1.2 # would run /usr/bin/printf instead
(unset -v LANG; printf -v var %.3f 1.2) # changes to $var lost afterwards
(ที่นี่ unsetting LANG เป็นวิธีการที่ผิดที่ทำให้แน่ใจว่า.
จะใช้และเข้าใจเป็นตัวคั่นทศนิยม. มันจะดีกว่าที่จะใช้LC_ALL=C printf...
สำหรับที่)
ด้วยเชลล์บางตัวคุณสามารถสร้างขอบเขตโลคัลสำหรับตัวแปรโดยใช้ฟังก์ชัน:
without() {
local "$1" # $1 variable declared as initially unset in bash¹
shift
"$@"
}
without LANG printf -v var %.3f 1.2
ด้วยzsh
, คุณยังสามารถใช้ฟังก์ชันที่ไม่ระบุชื่อ:
(){local ENV_VAR; command}
วิธีการนั้นจะไม่ทำงานในเชลล์บางตัว (เช่นเดียวกับที่ใช้เชลล์ Almquist) ซึ่งlocal
ไม่ได้ประกาศตัวแปรว่าเริ่มแรกแล้ว (แต่สืบทอดค่าและคุณสมบัติ) ในสิ่งเหล่านั้นคุณสามารถทำได้local ENV_VAR; unset ENV_VAR
แต่อย่าทำอย่างนั้นในmksh
หรือyash
( typeset
แทนที่จะlocal
เป็นแบบนั้น) เพราะวิธีนี้ใช้ไม่ได้ผลunset
จะเป็นการยกเลิกlocal
เท่านั้น
¹ระวังด้วยว่าในbash
นั้นโลคัลENV_VAR
(แม้ว่าจะไม่ได้ตั้งค่า) จะเก็บแอตทริบิวต์ส่งออกไว้ ดังนั้นถ้าcommand
เป็นฟังก์ชันที่กำหนดค่าให้ENV_VAR
ตัวแปรจะพร้อมใช้งานในสภาพแวดล้อมของคำสั่งที่เรียกว่าหลังจากนั้น unset ENV_VAR
จะล้างแอตทริบิวต์นั้น หรือคุณสามารถใช้local +x ENV_VAR
ซึ่งจะให้แน่ใจว่ากระดานชนวนสะอาด (ยกเว้นว่าตัวแปรที่ได้รับการประกาศให้อ่านอย่างเดียว แต่แล้วไม่มีอะไรที่คุณสามารถทำได้เกี่ยวกับมันbash
)
env '=foo' python -c 'import os; print os.environ[""]'
ลองยกตัวอย่างเช่น ฉันไม่คาดหวังว่าหลายคนจะต้องการตั้งค่าตัวแปรแบบนั้น
ไม่มีอะไรเทียบเท่าโดยตรงเท่าที่ฉันรู้ คุณสามารถใช้เชลล์ย่อย:
(unset ENV_VAR; exec command)
(unset ENV_VAR; exec somecommand)
ถ้าคุณต้องการที่จะเทียบเท่ากับต้นฉบับในประสิทธิภาพ (โดยการบริโภค subshell) ตามที่เป็นอยู่นี้จะเพิ่มทางแยกพิเศษ
command
เป็นคำสั่งสุดท้ายในการเรียกใช้ subshell
env -u
เปลี่ยนแปลงสภาพแวดล้อมเปลือกสำหรับหนึ่งซับแทนการจดจำว่ามันเป็น
คุณสามารถใช้ได้ ENV_VAR= command
นี่ไม่ได้ทำการยกเลิกการตั้งค่าตัวแปร แต่อาจมีประโยชน์ในหลายกรณี (โดยปกติเชลล์สคริปต์จะใช้test -n
เพื่อตรวจสอบว่ามีการตั้งค่าตัวแปร) หรือไม่:
$ export ENV_VAR=foo
$ mycommand
ENV_VAR: foo
$ ENV_VAR=bar mycommand
ENV_VAR: bar
$ ENV_VAR= mycommand
ENV_VAR:
command
เป็นทางเลือกที่โชคร้ายของตัวยึดเนื่องจากมีจริงคือในตัวคำสั่งโดยใช้ชื่อที่mycommand
หรือsomecommand
อาจจะเป็นนิสัยที่ดีกว่าในการเข้ามา