ความแตกต่างที่สำคัญที่สุดระหว่าง
bash -c "$1"
และ
eval "$1"
คือว่าอดีตทำงานใน subshell และหลังไม่ได้ ดังนั้น:
set -- 'var=something'
bash -c "$1"
echo "$var"
เอาท์พุท:
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
เอาท์พุท:
something
ฉันไม่มีความคิดว่าทำไมทุกคนจะใช้ความสามารถbashในการปฏิบัติการในลักษณะนั้น หากคุณต้องเรียกใช้ให้ใช้ POSIX รับประกันในshตัว หรือ(subshell eval)ถ้าคุณต้องการปกป้องสภาพแวดล้อมของคุณ
โดยส่วนตัวแล้วฉันชอบเชลล์.dotมากกว่าสิ่งอื่นใด
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
เอาท์พุท
something1
something2
something3
something4
something5
แต่คุณต้องการมันทั้งหมดหรือไม่
สาเหตุเดียวที่จะใช้อย่างใดอย่างหนึ่งจริง ๆ คือในกรณีที่ตัวแปรของคุณกำหนดหรือประเมินอื่นจริง ๆ หรือการแบ่งคำเป็นสิ่งสำคัญสำหรับผลลัพธ์
ตัวอย่างเช่น
var='echo this is var' ; $var
เอาท์พุท:
this is var
ใช้งานได้ แต่เพียงเพราะechoไม่สนใจเกี่ยวกับการนับอาร์กิวเมนต์
var='echo "this is var"' ; $var
เอาท์พุท:
"this is var"
ดู? สองคำพูดมาพร้อมเพราะผลของการขยายตัวของเปลือกของไม่ได้ประเมิน$varquote-removal
var='printf %s\\n "this is var"' ; $var
เอาท์พุท:
"this
is
var"
แต่ด้วยevalหรือsh:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
เอาท์พุท:
this is var
this is var
เมื่อเราใช้evalหรือshเชลล์ใช้การส่งผ่านครั้งที่สองที่ผลลัพธ์ของการขยายและประเมินว่ามันเป็นคำสั่งที่มีศักยภาพเช่นกันดังนั้นราคาจะสร้างความแตกต่าง คุณยังสามารถทำสิ่งต่อไปนี้
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
เอาท์พุท
this is var
e='echo foo'; $eทำงานได้ดี