ความแตกต่างระหว่างคำสั่งคืออะไร
$ env FOO=bar baz
และ
$ FOO=bar baz
มีผลกระทบอะไรenvบ้าง
ความแตกต่างระหว่างคำสั่งคืออะไร
$ env FOO=bar baz
และ
$ FOO=bar baz
มีผลกระทบอะไรenvบ้าง
คำตอบ:
พวกมันมีหน้าที่เทียบเท่า
แตกต่างที่สำคัญคือการที่env FOO=bar bazเกี่ยวข้องกับการเรียกกระบวนการตัวกลางระหว่างเปลือกและbazที่เช่นเดียวกับเปลือกจะเรียกโดยตรงFOO=bar baz
ดังนั้นในเรื่องที่เป็นที่ต้องการbazFOO=bar baz
สถานการณ์เดียวที่ฉันพบว่าตัวเองกำลังใช้env FOO=barอยู่คือที่ฉันต้องส่งคำสั่งไปยังคำสั่งอื่น
เป็นตัวอย่างเฉพาะสมมติว่าฉันมีสคริปต์ตัวตัดคำที่ทำการแก้ไขบางอย่างของสภาพแวดล้อมและจากนั้นเรียกexecใช้คำสั่งที่ส่งผ่านไปเช่น:
#!/bin/bash
FOO=bob
some stuff
exec "$@"
หากคุณดำเนินการตามmyscript FOO=bar bazนั้นexecจะทำให้เกิดข้อผิดพลาดตามที่exec FOO=bar bazไม่ถูกต้อง
แต่คุณเรียกมันว่าmyscript env FOO=bar bazสิ่งที่ถูกดำเนินการexec env FOO=bar bazและมีผลสมบูรณ์
FOO=bar exec bazดังนั้นคุณไม่จำเป็นต้องenvอยู่ในจุดสุดท้าย
execบางสิ่งมันใช้สภาพแวดล้อมปัจจุบันของคุณหรือไม่?
sudo FOO=bar baz env
FOO=barสคริปต์ หากFOOไม่เสมอbarไปฉันไม่ต้องการเขียนโค้ดอย่างหนักและส่งผ่านแทน
exec FOO=bar exec baz
ในตัวอย่างนี้ไม่มีความแตกต่างที่มีประสิทธิภาพสมมติว่าเชลล์ของคุณเป็นเชลล์ที่เข้ากันได้กับ POSIX และสมมติว่าbazเป็นไฟล์ที่เรียกใช้งานได้และไม่ใช่เชลล์ในตัว
หากเชลล์ของคุณไม่ใช่เชลล์ที่เข้ากันได้กับ POSIX ตัวอย่างเช่นcshหรือtcshไวยากรณ์
FOO=bar baz
ไม่ทำงานและไม่มีไวยากรณ์เชลล์เทียบเท่า สำหรับเชลล์เหล่านั้นenvคำสั่งเป็นวิธีเดียวที่จะแทนที่หรือฉีดตัวแปรสภาพแวดล้อมสำหรับคำสั่งเดียว
ถ้าbazเป็น shell builtin เราจะfcยกตัวอย่างเช่นแล้วenvจะไม่ให้ผลลัพธ์เดียวกันเพราะenvกำลังประมวลผลกระบวนการใหม่แทนที่จะเรียกใช้โดยตรงโดย command command นอกจากนี้ยังไม่มีการfcปฏิบัติการจะสามารถทำงานเป็นเพียงเปลือก builtin เพราะวิธีการที่จะมีปฏิสัมพันธ์กับสภาพแวดล้อมเปลือกและอื่น ๆenvจะไม่เคยทำงานร่วมกับ builtin fcเช่น
นอกจากนี้ยังenvมี-iตัวเลือกซึ่งช่วยให้คุณสามารถเริ่มคำสั่งในสภาพแวดล้อมที่ว่างเปล่าที่มีชุดของตัวแปรสภาพแวดล้อมที่ระบุเท่านั้น ดังนั้นenvจะมีประโยชน์มากสำหรับกระบวนการเริ่มต้นในสภาพแวดล้อมที่ผ่านการฆ่าเชื้อเช่น
env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz
tcshฉันจะเขียน(setenv FOO bar; baz)เพื่อรับฟังก์ชั่นที่เทียบเท่า
นอกจากสิ่งที่ได้กล่าวไปแล้ว
VAR=value cmd args > redirs
เป็นเปลือกคุณลักษณะ (บอร์น / POSIX) คุณจะ จำกัด cmdในชื่อของตัวแปรสภาพแวดล้อมที่คุณส่งผ่านไปยัง พวกเขาจะต้องเป็นชื่อตัวแปรเชลล์ที่ถูกต้องและต้องไม่เป็นตัวแปรแบบอ่านอย่างเดียวหรือพิเศษสำหรับเชลล์
ตัวอย่างเช่นคุณไม่สามารถทำได้:
1=foo cmd
หรือ
+++=bar cmd
bash ไม่อนุญาตให้คุณทำ:
SHELLOPTS=xtrace cmd
ในขณะที่คุณสามารถทำได้:
env 1=foo cmd
env +++=bar cmd
env '=baz' cmd
(ไม่ใช่ที่คุณต้องการหรือควรจะทำอย่างนั้น) หรือ:
env SHELLOPTS=xtrace cmd
(บางครั้งฉันต้องทำอย่างนั้น)
โปรดทราบว่าในขณะที่envคุณยังไม่สามารถผ่านสตริงตัวแปรสภาพแวดล้อมที่ไม่มี=(ไม่ใช่ว่าคุณต้องการทำเช่นนั้น)
การใช้งานอย่างหนึ่งenvคือการอนุญาตให้$PATHค้นหาไฟล์ที่เรียกใช้งานได้ในแนว Shebang (เนื่องจากenvพิจารณา$PATHเมื่อค้นหาไฟล์ที่เรียกทำงานได้) สิ่งนี้มีประโยชน์หากปฏิบัติการที่คุณต้องการเรียกใช้อาจอยู่ในสถานที่ที่แตกต่างกันบนเครื่องที่แตกต่างกัน ตัวอย่างเช่น,
#!/usr/bin/env perl
ในบรรทัดแรกของสคริปต์ที่มีชุดบิตที่เรียกทำงานได้จะเรียกใช้งานสคริปต์นี้ด้วย Perl ไม่ว่าจะติดตั้งใน/usr/bin/perlหรือใน/usr/local/bin/perlหรือในสถานที่ที่แตกต่างอย่างสิ้นเชิงตราบใดที่ไดเรกทอรีอยู่ในเส้นทาง
แน่นอนว่าการค้นหาเส้นทางมาพร้อมกับความเสี่ยงที่เพิ่มขึ้น แต่จากนั้นความเสี่ยงนั้นไม่ใหญ่กว่าถ้าคุณเขียนไว้อย่างชัดเจนperl yourscript.plซึ่งจะค้นหา Perl ในเส้นทางการค้นหาด้วย
อีกครั้งเมื่อenvมีประโยชน์จริง ๆ คือถ้าคุณต้องการควบคุมสภาพแวดล้อมอย่างสมบูรณ์ ฉันเรียกใช้โปรแกรมเซิร์ฟเวอร์ (Informix ในกรณีที่คุณไม่สามารถเดาได้) ซึ่งมีสภาพแวดล้อมที่ฉันต้องการควบคุมอย่างสมบูรณ์ ฉันรันโดยใช้envที่ส่วนท้ายของสคริปต์ซึ่งตั้งค่าตัวแปรให้เป็นค่าที่ถูกต้อง:
env -i HOME="$IXD" \
INFORMIXDIR="$IXD" \
INFORMIXSERVER="$IXS" \
${IXC:+INFORMIXCONCSMCFG="$IXC"} \
${IXH:+INFORMIXSQLHOSTS="$IXH"} \
IFX_LISTEN_TIMEOUT=3 \
ONCONFIG="onconfig.$IXS" \
PATH="/bin:/usr/bin:$IXD/bin" \
SHELL=/bin/ksh \
TZ=UTC0 \
$ONINIT "$@"
-iตัวเลือก zaps สภาพแวดล้อมที่มีอยู่ VAR=valueตัวเลือกที่ตามมาตั้งค่าตัวแปรสภาพแวดล้อมที่ฉันต้องการตั้งค่า ชื่อของโปรแกรมที่อยู่ใน$ONINITและอาร์กิวเมนต์บรรทัดคำสั่งใด ๆ "$@"จะถูกส่งผ่านคำต่อคำกับ
การ${IXH:+INFORMIXSQLHOSTS="$IXH"}สร้างจะผ่านINFORMIXSQLHOSTS="$IXH"ไปenvหาก$IXHถูกตั้งค่าเป็นค่าที่ไม่ว่างเปล่า