ฟังก์ชั่นทำงานเป็นกระบวนการย่อยใน Bash หรือไม่?


28

ในBash-Scripting Guide ขั้นสูงในตัวอย่างที่ 27-4 , 7-line จากด้านล่างฉันได้อ่าน:

ฟังก์ชั่นทำงานเป็นกระบวนการย่อย

ฉันทำการทดสอบใน Bash และดูเหมือนว่าข้อความข้างต้นผิด

ค้นหาในไซต์นี้ Bash Man และเครื่องมือค้นหาของฉัน

คุณมีคำตอบและต้องการอธิบายหรือไม่?


12
ดังที่ระบุไว้คู่มือนั้นทำให้เข้าใจผิดในสุดขีด ฉันแนะนำWoolash Bash Guideแทน
สัญลักษณ์แทน

คำตอบ:


36

ขั้นสูงทุบตี Scripting คู่มือไม่ได้เสมอที่เชื่อถือได้และสคริปต์ตัวอย่างของการปฏิบัติที่มีออกลงวันเช่นใช้เลิกใช้อย่างมีประสิทธิภาพ backticks เพื่อทดแทนคำสั่งคือมากกว่า`command`$(command)

ในกรณีนี้มันไม่ถูกต้องอย่างโจ๋งครึ่ม

ส่วนของฟังก์ชั่นเชลล์ในคู่มือทุบตี (บัญญัติ) ระบุอย่างชัดเจนว่า

ฟังก์ชั่นเชลล์จะดำเนินการในบริบทเชลล์ปัจจุบัน ไม่มีกระบวนการใหม่ถูกสร้างขึ้นเพื่อตีความพวกเขา


10
"คู่มือทุบตีสคริปต์ขั้นสูงโดยทั่วไปไม่น่าเชื่อถือ" เป็นเรื่องจริงมาก
John1024

1
คุณสามารถให้การอ้างอิงเพื่อสนับสนุนประโยคแรกของคุณได้หรือไม่?
Will Vousden

5
@ WillVousden การอ้างอิงจะมีลักษณะอย่างไรที่นี่? กลุ่มตัวอย่างของข้อบกพร่องทางเทคนิคของคู่มือหรือไม่ เอกสารที่ผู้เชี่ยวชาญในชุมชนทุบตีได้ระบุไว้ก่อนหน้านี้ว่าไม่น่าเชื่อถือหรือไม่ มันจะช่วยได้หรือไม่หากสมาชิกสแต็คโอเวอร์โฟลว์ที่มีตราทองเป็น bash เพิ่งตกลงในความคิดเห็น : p
kojiro

3
@ WillVousden ฉันไม่คิดว่าสิ่งที่คุณต้องการมีอยู่ในรูปแบบที่เชื่อถือได้เอง Mendel Cooper ได้อัปเดตและแก้ไขปัญหาเกี่ยวกับคำแนะนำในอดีต แต่ไม่มีตัวติดตามข้อผิดพลาดสาธารณะหรือรายการ errata (บางทีนั่นอาจเป็นคำที่น่ากลัวที่สุดที่ฉันสามารถทำได้) ดังนั้นเมื่อเราพบข้อบกพร่อง (การรับรู้หรือจริง) ทั้งหมดที่เราทำได้คือส่งอีเมลถึงผู้เขียนและหวังว่าจะเป็นสิ่งที่ดีที่สุด
kojiro

3
@ WillVousden, ... หากคุณต้องการประวัติว่าฉันทามติใน freenode #bash channel นานเท่าไหร่ควรหลีกเลี่ยง ABS ให้ดูที่wooledge.org/~greybot/meta/abs - ฟิลด์ที่สองในแต่ละบรรทัด เป็นเวลาและครั้งแรกคือชื่อผู้ใช้; ฉันจะหวังว่าการยืนยันว่าชื่อผู้ใช้ที่เป็นปัญหานั้นพอเพียงสำหรับผู้ที่เคารพนับถือ
Charles Duffy

32

ฟังก์ชั่นรั้งปีกกาจะทำงานภายในกระบวนการเรียกเปลือกเว้นแต่พวกเขาต้องการ subshell ของตัวเองซึ่งก็คือ:

  • เมื่อคุณเรียกใช้ในพื้นหลังด้วย &
  • เมื่อคุณเรียกใช้เป็นลิงก์ในไปป์ไลน์

การเปลี่ยนเส้นทางหรือ env พิเศษ ตัวแปรจะไม่บังคับให้ subshell ใหม่:

hw(){
    echo hello world from $BASHPID
    echo var=$var
} 
var=42 hw >&2
echo $BASHPID  #unexports var=42 and restores stdout here

หากคุณกำหนดฟังก์ชันด้วยวงเล็บแทนที่จะเป็น curlies:

hw()(
  echo hello world from $BASHPID
)
hw 
echo $BASHPID

มันจะทำงานในกระบวนการใหม่เสมอ

การทดแทนคำสั่ง$()สร้างกระบวนการใน bash เสมอ (แต่ไม่ใช่ใน ksh หากคุณเรียกใช้ builtins ภายใน)


ฉันไม่ทราบว่าf() (...)ได้รับอนุญาต มีคำจำกัดความอื่นนอกเหนือจาก{...}และ(...)? ใน Bash ฉันยังไม่ได้เป็นคนอื่นเลย
Tomasz

1
@tomas คุณสามารถใช้function hw { echo hello world; } ไวยากรณ์ (ไม่จำเป็น()ถ้าคุณพิมพ์ออกมาfunctionและคุณสามารถระบุการเปลี่ยนเส้นทางได้หลังจบการแข่งขัน}หรือ)ตามhw(){ echo error; } >&2มานั่นเป็นเรื่องของมัน
PSkocik

2
นี่คือคำตอบที่ฉันคิดในทันทีและมันถูกต้องอย่างแน่นอน ควรได้รับการโหวตว่าเป็นคำตอบที่ถูกต้อง f()(...)ดำเนินการเชลล์ของตัวเองเสมอโดยที่f(){...}ไม่ทำ
rexkogitans

11
ฟังก์ชัน bash NB ยอมรับคำสั่งผสมใด ๆ ดังนั้นจึงfoo() [[ x = x ]]เป็นคำจำกัดความของฟังก์ชันที่ถูกต้องเช่นกัน แต่ถ้าคุณมองไปที่ฟังก์ชั่นที่มีคุณจะเห็นว่านี้ยังคงเป็นน้ำตาลประโยคสำหรับtype foo foo() { [[ x = x ]]; }เดียวกันเป็นจริงของการทำงาน subshell: กลายเป็นbar() ( : ) bar() { ( : ); }
kojiro

1
@kojiro ดี +1 ไม่รู้ว่า
PSkocik

9

คำสั่งในคำถามจากตัวอย่างนั้นดูเหมือนว่า:

echo ${arrayZ[@]/%e/$(replacement)}

ตัวอย่างกล่าวในภายหลัง:

#    $( ... ) is command substitution.
#    A function runs as a sub-process.

เป็นกุศล ABS คู่มือสิ่งที่พวกเขาเห็นได้ชัดว่าหมายถึงการเขียนเป็นฟังก์ชั่นที่ทำงานอยู่ภายในแทนคำสั่งและคำสั่งที่อยู่ภายในคำสั่งเปลี่ยนตัววิ่งในsubshell


นั่นเป็นสิ่งที่ทำให้เข้าใจผิดมาก ขอบคุณสำหรับการตีความของคุณ
Tomasz

5
@ โทมัส"ทำให้เข้าใจผิดมาก" ใช่แล้ว ตรงกันข้ามกับ ABS Guide Greg's Wikiเป็นแหล่งข้อมูลทุบตีขั้นสูงที่ยอดเยี่ยม
John1024

1
ไชโย อะไรความคิดเห็นของคุณเกี่ยวกับเรื่องนี้: wiki.bash-hackers.org/start ?
Tomasz

@ โทมัสฉันไม่มีความรู้โดยตรงเกี่ยวกับสิ่งนั้น
John1024

2
@ โทมัส, ... ความคิดเห็นของฉันเกี่ยวกับ bash-hackers wiki คือมันเป็นแหล่งข้อมูลที่ยอดเยี่ยม ฉันไม่ได้ผ่านมันอย่างละเอียดเหมือนกับที่ฉันมีวิกิว่า Wooledge แต่มีแนวโน้มที่จะถูกต้องและเขียนอย่างแม่นยำ
Charles Duffy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.