มีความแตกต่างระหว่างการเพิ่มคู่ค่าชื่อให้กับคำสั่งและการใช้ env ใน bash หรือไม่?


19

สมมติว่าผมเรียกA=B commandและในenv A=B command bashมีสถานการณ์ใดบ้างที่อาจมีความแตกต่างระหว่างการขอร้องทั้งคู่?

คำตอบ:


26

พวกเขาให้บริการวัตถุประสงค์เดียวกัน (ผ่าน vars env ที่กำหนดให้กับคำสั่ง) อย่างไรก็ตามความแตกต่างที่น่าสังเกต:

A=B command

เป็นโครงสร้างของเชลล์ (Bourne / POSIX / rc)

ตัวอย่างเช่นคุณสามารถทำได้:

A=B find . -exec cmd '{}' +

หรือ:

find . -exec env A=B cmd '{}' +

แต่คุณไม่สามารถทำได้:

find . -exec A=B cmd '{}' +

เนื่องจากfindไม่ได้เรียกใช้เชลล์เพื่อเรียกใช้คำสั่งนั้น

ในขณะenvที่เป็นคำสั่งภายนอกคุณไม่สามารถทำ:

f() { ...; }
env A=B f

หรือ:

env A=B eval '...'

นอกจากนี้:

A=B cmd

ใช้ได้กับ env vars ที่เป็นชื่อตัวแปรเชลล์ที่ถูกต้องเท่านั้น คุณต้องการenvชื่อ env var อื่น ๆ :

env 'my var=foo' cmd...

bashรีเซ็ต_ตัวแปร:

bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx

ในzsh, ARGV0และSTTYมีความหมายพิเศษในบริบทที่:

STTY=-echo cat

ทำงานcatโดยechoปิดการทำงานของเทอร์มินัล และ:

ARGV0=foo cmd

ทำงานcmdด้วยเป็นของตนfooargv[0]

envหากคุณไม่ต้องการที่ประมวลผลพิเศษที่คุณต้องใช้

โปรดทราบว่าsudoรองรับ:

sudo A=B cmd

มันไม่ได้ใช้เปลือกหรือenvทำสิ่งนั้น มันทำด้วยตัวเอง

มันสามารถผ่านตัวแปรที่มีชื่อเริ่มต้นใด ๆ -ยกเว้นผู้ที่มี

การมอบหมายเป็นโครงสร้างของเชลล์ในขณะที่เครื่องหมายเท่ากับในอาร์กิวเมนต์ของenvไม่มีความหมายพิเศษกับเชลล์ดังนั้นA=$B cmdจะปลอดภัยในขณะที่env A="$B" cmd(หรือsudo A="$B" cmd) ต้องมีเครื่องหมายคำพูดคู่

สนับสนุนA=B cmdไวยากรณ์ในเชลล์ของ Bourne และrcตระกูลเท่านั้น (ไม่ใช่es) เช่นในเปลือกหอยcshหรือfishครอบครัวคุณต้องหันไปenvใช้

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