ฉันกำลังศึกษาสคริปต์เปลือกทุบตีและฉันต้องการที่จะทราบความแตกต่างระหว่างและ(...)
{...}
หนึ่งจะเลือกระหว่างทั้งสองเมื่อเขียนสคริปต์ได้อย่างไร
ฉันกำลังศึกษาสคริปต์เปลือกทุบตีและฉันต้องการที่จะทราบความแตกต่างระหว่างและ(...)
{...}
หนึ่งจะเลือกระหว่างทั้งสองเมื่อเขียนสคริปต์ได้อย่างไร
คำตอบ:
หากคุณต้องการให้ผลข้างเคียงของรายการคำสั่งมีผลต่อเชลล์ปัจจุบันของคุณให้ใช้{...}
หากคุณต้องการยกเลิกผลข้างเคียงใด ๆ ให้ใช้(...)
ตัวอย่างเช่นฉันอาจใช้ subshell ถ้าฉัน:
$IFS
สำหรับคำสั่งบางอย่าง แต่ฉันไม่ต้องการที่จะเปลี่ยนแปลง$IFS
ทั่วโลกสำหรับเปลือกปัจจุบันcd
อยู่ที่ไหนซักแห่ง แต่ฉันไม่ต้องการเปลี่ยน$PWD
เปลือกปัจจุบันควรสังเกตว่าสามารถใช้วงเล็บในการกำหนดฟังก์ชันได้:
การใช้งานปกติ: วงเล็บปีกกา: ร่างกายฟังก์ชั่นรันในเปลือกปัจจุบัน; ผลข้างเคียงยังคงอยู่หลังจากฟังก์ชั่นเสร็จสมบูรณ์
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
การใช้งานที่ผิดปกติ: วงเล็บ: ร่างกายฟังก์ชั่นดำเนินการใน subshell; ผลข้างเคียงจะหายไปเมื่อออกจาก subshell
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
local
คำสำคัญจะช่วยขจัดมลพิษนั้นได้อีกต่อไป
pwd; (count_tmp); pwd;
จากเอกสารทุบตีอย่างเป็นทางการ:
()
( list )
การวางรายการคำสั่งระหว่างวงเล็บทำให้เกิดสภาวะแวดล้อม subshell ที่จะสร้างและแต่ละคำสั่งในรายการที่จะดำเนินการใน subshell นั้น เนื่องจากรายการจะถูกดำเนินการใน subshell การกำหนดตัวแปรจึงไม่ยังคงมีผลหลังจาก subshell เสร็จสมบูรณ์
{}
{ list; }
การวางรายการคำสั่งระหว่างวงเล็บปีกกาทำให้รายการถูกเรียกใช้งานในบริบทเชลล์ปัจจุบัน ไม่มีการสร้างเชลล์ย่อย จำเป็นต้องใช้รายการอัฒภาค (หรือขึ้นบรรทัดใหม่)
โค้ดใน '{}' ถูกเรียกใช้ในเธรด / กระบวนการ / สภาพแวดล้อมปัจจุบันและการเปลี่ยนแปลงจะถูกเก็บรักษาไว้เพื่อให้ชัดเจนยิ่งขึ้นรหัสจะถูกรันในขอบเขตปัจจุบัน
โค้ดใน '()' ถูกเรียกใช้ภายในกระบวนการลูกที่แยกต่างหากของการทุบตีที่ถูกทิ้งหลังจากประมวลผลแล้ว กระบวนการย่อยนี้มักถูกเรียกว่า sub-shell และอาจถูกมองว่าเป็นขอบเขตใหม่ที่เหมือนเด็ก
เป็นตัวอย่างให้พิจารณาดังต่อไปนี้ ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
โปรดสังเกตในตัวอย่างแรกด้วย '{}' ตัวแปรยังคงถูกตั้งค่าแม้หลังจากปิด '}' ในขณะที่ในตัวอย่างด้วย '()' ตัวแปรจะไม่ถูกตั้งค่านอกขอบเขตของ '()'
(...)
ใช้เพื่อเรียกใช้รหัสใน sub-shell โค้ดที่ใช้สิบสอง{...}
จะไม่ถูกใช้ในเชลล์ย่อย