อะไรคือความแตกต่างระหว่างคำสั่งreturnและexitคำสั่งในฟังก์ชั่น Bash ที่เกี่ยวกับรหัสทางออก?
อะไรคือความแตกต่างระหว่างคำสั่งreturnและexitคำสั่งในฟังก์ชั่น Bash ที่เกี่ยวกับรหัสทางออก?
คำตอบ:
จากman bashบนreturn [n];
ทำให้ฟังก์ชั่นหยุดการทำงานและคืนค่าที่ระบุโดย n ไปยังผู้เรียก หากไม่ได้ระบุไว้ n สถานะการส่งคืนจะเป็นของคำสั่งสุดท้ายที่ดำเนินการในเนื้อความของฟังก์ชัน
... เมื่อexit [n]:
ทำให้เชลล์ออกโดยมีสถานะเป็น n หากไม่ได้ระบุไว้สถานะการออกจะเป็นของคำสั่งสุดท้ายที่ดำเนินการ กับดักบน EXIT ถูกดำเนินการก่อนที่เชลล์จะหยุดทำงาน
แก้ไข:
ตามการแก้ไขคำถามเกี่ยวกับรหัสออกของคุณreturnไม่มีอะไรเกี่ยวข้องกับรหัสทางออก รหัสออกมีไว้สำหรับแอปพลิเคชัน / สคริปต์ไม่ใช่ฟังก์ชัน ดังนั้นในเรื่องนี้คำเดียวที่ชุดรหัสทางออกของสคริปต์ (หนึ่งที่สามารถจับโดยโปรแกรมเรียกใช้$?ตัวแปรเชลล์) exitคือ
แก้ไข 2:
การอ้างถึงคำสั่งสุดท้ายของฉันexitทำให้เกิดความคิดเห็น มันถูกสร้างขึ้นเพื่อแยกความแตกต่างreturnและexitเพื่อความเข้าใจของ OP และในความเป็นจริง ณจุดใด ๆ ที่กำหนดของโปรแกรม / เชลล์สคริปต์exitเป็นวิธีเดียวในการสิ้นสุดสคริปต์ด้วยรหัสออกจากกระบวนการเรียก
ทุกคำสั่งดำเนินการในเปลือกผลิตท้องถิ่น "รหัสทางออก": มันกำหนด$?ตัวแปรรหัสที่สามารถนำมาใช้กับif,   &&และผู้ประกอบการอื่น ๆ ที่จะตามเงื่อนไขรันคำสั่งอื่น ๆ
รหัสทางออกเหล่านี้ (และค่าของ$?ตัวแปร) จะถูกรีเซ็ตโดยการดำเนินการคำสั่งแต่ละครั้ง
อนึ่งรหัสทางออกของคำสั่งสุดท้ายที่เรียกใช้โดยสคริปต์จะใช้เป็นรหัสออกจากสคริปต์เองตามที่เห็นโดยกระบวนการเรียก
ในที่สุดฟังก์ชั่นเมื่อเรียกใช้ทำหน้าที่เป็นคำสั่งเชลล์ที่เกี่ยวกับรหัสออก รหัสทางออกของฟังก์ชั่น ( ภายในฟังก์ชั่น) returnจะถูกตั้งค่าโดยใช้ ดังนั้นเมื่อในการทำงานreturn 0ของฟังก์ชั่นการดำเนินการฟังก์ชั่นสิ้นสุดลงให้รหัสออกจาก 0
func(){ return 50; };func;echo $?เสียงสะท้อน 50. ดังนั้น$?ตัวแปรเปลือกดูเหมือนจะไม่ถูก จำกัด exitให้
                    $?ขยายเป็นสถานะออกของไปป์ไลน์เบื้องหน้าที่เรียกใช้งานล่าสุด" ทางออกนั้นอาจมาจากเชลล์ในรูปแบบของการเรียกไปที่exit(หรือกดปุ่มสิ้นสุดสคริปต์) หรือในรูปแบบของการเรียกไปยังreturnภายในฟังก์ชัน
                    $? กระบวนการ / สคริปต์ปัจจุบันถูก จำกัดexitหรือผลลัพธ์ของคำสั่งสุดท้ายที่ดำเนินการโดยสคริปต์นี้ ดังนั้นหากบรรทัดสคริปต์สุดท้ายของคุณคือการเรียกใช้ฟังก์ชันนั้นและฟังก์ชันนั้นจะคืนค่า 50 ใช่$?คุณจะสร้างกระบวนการที่เรียกว่าคุณคือ 50 อย่างไรก็ตามนั่นไม่ได้เกี่ยวข้องกับสิ่งreturnนั้นเพราะนี่คือ จำกัด ให้สคริปต์ปัจจุบัน มันจะถูกส่งกลับเฉพาะเมื่อการเรียกใช้ฟังก์ชันนี้เป็นประโยคสุดท้ายของสคริปต์ exitอย่างไรก็ตามให้สคริปต์ดำเนินการให้เสร็จสิ้นและส่งคืนค่านั้นตาม$? กระบวนการเรียกใช้
                    returnไม่มีอะไรเกี่ยวข้องกับรหัสทางออก" การทดลองบอกฉันว่าไม่มีความแตกต่างการทำงานระหว่างโค้ดส่งคืนของฟังก์ชันและโค้ดออกของสคริปต์
                    returnจะทำให้ฟังก์ชันปัจจุบันออกนอกขอบเขตในขณะที่exitจะทำให้สคริปต์สิ้นสุด ณ จุดที่เรียกใช้ นี่คือตัวอย่างโปรแกรมที่จะช่วยอธิบายสิ่งนี้:
#!/bin/bash
retfunc()
{
    echo "this is retfunc()"
    return 1
}
exitfunc()
{
    echo "this is exitfunc()"
    exit 1
}
retfunc
echo "We are still here"
exitfunc
echo "We will never see this"$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()$?ใน
                    echo fnord | while read x; do exitfunc; done; echo "still here"จะพิมพ์ "ยังอยู่ที่นี่" ดูเหมือนว่ามีการออกเฉพาะwhileเชลล์ย่อยในสถานการณ์นี้
                    done || exit $?แต่นั้นน่าเกลียดและไม่เทียบเท่ากันอย่างแม่นยำ
                    returnจะทำให้ฟังก์ชั่นปัจจุบันหรือสคริปต์ที่มาจากขอบเขต '' '
                    ฉันไม่คิดว่าใครจะตอบคำถามได้อย่างสมบูรณ์เพราะพวกเขาไม่ได้อธิบายวิธีการใช้งานของทั้งสอง ตกลงฉันคิดว่าเรารู้ว่าการออกจากการฆ่าสคริปต์ซึ่งจะถูกเรียกและคุณสามารถกำหนดสถานะให้กับมันเช่นออกหรือออก 0 หรือออก 7 และอื่น ๆ สามารถใช้เพื่อกำหนดวิธีที่สคริปต์ถูกบังคับให้หยุดถ้าเรียกโดยสคริปต์อื่นเป็นต้นพอออก
return เมื่อเรียกว่าจะส่งคืนค่าที่ระบุเพื่อระบุพฤติกรรมของฟังก์ชั่นมักจะเป็น 1 หรือ 0 ตัวอย่างเช่น:
    #!/bin/bash
    isdirectory() {
      if [ -d "$1" ]
      then
        return 0
      else
        return 1
      fi
    echo "you will not see anything after the return like this text"
    }ตรวจสอบเช่นนี้:
    if isdirectory $1; then echo "is directory"; else echo "not a directory"; fiหรือเช่นนี้
    isdirectory || echo "not a directory"ในตัวอย่างนี้การทดสอบสามารถใช้เพื่อระบุว่าพบไดเรกทอรี โปรดสังเกตว่าสิ่งใดหลังจากการส่งคืนจะไม่ถูกดำเนินการในฟังก์ชัน 0 เป็นจริง แต่เท็จเป็น 1 ในเชลล์ซึ่งแตกต่างจากโปรแกรมอื่น ๆ
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชั่น: http://www.linuxjournal.com/content/return-values-bash-functions
หมายเหตุ: ฟังก์ชั่น isdirectory มีวัตถุประสงค์เพื่อการเรียนการสอนเท่านั้น นี่ไม่ควรเป็นวิธีที่คุณทำเช่นนั้นในสคริปต์จริง
test -d $1เพื่อให้ได้ผลลัพธ์เดียวกัน if <check> return else returnไม่เคยทำ <check>เพียงอย่างเดียวจะทำสิ่งเดียวกันในทุกภาษาที่ฉันรู้
                    isdirectory() { [ -d "$1" ]; }จะทำงานอย่างแม่นยำเหมือนกับที่คุณมีที่นี่: ค่าส่งคืนเริ่มต้นของฟังก์ชั่นเชลล์ไม่ว่าจะถึงจุดสิ้นสุดของรหัสหรือโดยreturnไม่มีข้อโต้แย้งเป็นของ คำสั่งล่าสุด
                    returnข้อความ มันเป็นความจริงที่ตัวอย่างของเขาเรียบง่ายและไม่ควรใช้ในการผลิต แต่มันง่ายดังนั้นมันจึงทำงานของเขาได้ดี ไม่มีอะไรผิดปกติกับมัน
                    โปรดจำไว้ว่าฟังก์ชั่นนั้นอยู่ภายในสคริปต์และโดยปกติจะส่งคืนจากสิ่งที่ถูกเรียกโดยใช้คำสั่ง return การเรียกสคริปต์ภายนอกเป็นอีกเรื่องหนึ่งโดยสิ้นเชิงและสคริปต์มักจะยุติด้วยข้อความสั่ง exit
ความแตกต่าง "ระหว่างคำสั่ง return และ exit ในฟังก์ชั่น BASH ที่เกี่ยวกับรหัสทางออก" นั้นน้อยมาก ทั้งคืนสถานะไม่ใช่ค่าต่อ se สถานะศูนย์หมายถึงความสำเร็จในขณะที่สถานะอื่น ๆ (1 ถึง 255) หมายถึงความล้มเหลว คำสั่ง return จะกลับไปที่สคริปต์จากที่ซึ่งถูกเรียกในขณะที่คำสั่ง exit จะจบสคริปต์ทั้งหมดจากที่ใดก็ตามที่พบ
return 0  # returns to where the function was called.  $? contains 0 (success).
return 1  # returns to where the function was called.  $? contains 1 (failure).
exit 0  # exits the script completely.  $? contains 0 (success).
exit 1  # exits the script completely.  $? contains 1 (failure).หากฟังก์ชั่นของคุณลงท้ายด้วยไม่มีคำสั่งส่งคืนสถานะของคำสั่งสุดท้ายที่ดำเนินการจะถูกส่งกลับเป็นรหัสสถานะ (และจะถูกวางไว้ใน$?)
โปรดจำไว้ว่าการกลับมาและออกให้กลับรหัสสถานะที่ 0-255 $?ในใช้ได้ คุณไม่สามารถสิ่งอื่นใดลงในรหัสสถานะ (เช่นส่งคืน "cat"); มันจะไม่ทำงาน แต่สคริปต์สามารถส่งกลับสาเหตุต่าง ๆ 255 สาเหตุที่ทำให้เกิดความล้มเหลวโดยใช้รหัสสถานะ
คุณสามารถตั้งค่าตัวแปรที่มีอยู่ในสคริปต์การโทรหรือผลลัพธ์เสียงสะท้อนในฟังก์ชั่นและใช้การทดแทนคำสั่งในสคริปต์การโทร; แต่วัตถุประสงค์ของการส่งคืนและออกคือการส่งรหัสสถานะไม่ใช่ค่าหรือผลลัพธ์การคำนวณอย่างที่ใคร ๆ คาดหวังในภาษาการเขียนโปรแกรมเช่น C
บางครั้งคุณเรียกใช้สคริปต์ที่ใช้หรือ.source
. a.shหากคุณรวมถึงexitในa.shนั้นมันจะไม่เพียง แต่ยุติสคริปต์ แต่จบเซสชันเปลือกของคุณ
หากคุณรวม a returnไว้ในตัวa.shมันจะหยุดการประมวลผลสคริปต์
return: can only 'return' from a function or sourced scriptซึ่งทำให้สคริปต์ทั่วไปไม่เหมาะสม
                    allสถานการณ์ การใช้.หรือsourceเรียกใช้สคริปต์ในเชลล์ปัจจุบันแทนที่จะวางไข่เชลล์ย่อย สคริปต์ต้องรู้ว่าจะใช้อย่างไร ความฉิบหายให้กับผู้ใช้ที่ทำตรงข้าม ส่วนตัวผมขอแนะนำให้อ่านสคริปต์ก่อนที่จะเรียกใช้ในครั้งแรก
                    trapฟังก์ชั่นสำหรับการERR EXITแล้วครั้งแรกที่บันทึกรหัสทางออกของคำสั่งที่ล้มเหลวerrCode=$?แล้วออกจากสคริปต์ (ที่มาหรือไม่) มีreturn $errCode || exit $errCodeที่||หมายถึง "ถ้าผมไม่สามารถกลับเพราะผมก็ไม่ได้มา เพียงออกจากแทน "
                    ในคำง่าย ๆ (ส่วนใหญ่สำหรับมือใหม่ในการเขียนโปรแกรม) เราสามารถพูดได้ว่า
`return` : exits the function,
`exit()` : exits the program(called as process while running)นอกจากนี้หากคุณสังเกตว่านี่เป็นพื้นฐานมาก แต่ ...
`return` : is the keyword
`exit()` : is the functionexitจะมีฟังก์ชั่นไม่returnมากไปกว่านั้น พวกเขาเป็นคำสั่งในตัว พวกเขาไม่ได้จองคำ
                    exitยุติกระบวนการปัจจุบัน ; มีหรือไม่มีรหัสทางออกพิจารณาระบบนี้มากกว่าฟังก์ชั่นโปรแกรม โปรดทราบว่าเมื่อการจัดหาexitจะสิ้นสุดเชลล์อย่างไรก็ตามเมื่อทำงานจะเป็นเพียงexitสคริปต์
return จากฟังก์ชั่นกลับไปที่คำแนะนำหลังจากการโทรโดยมีหรือไม่มีรหัสส่งคืน returnเป็นทางเลือกและเป็นนัยในตอนท้ายของฟังก์ชัน returnสามารถใช้ได้ภายในฟังก์ชั่นเท่านั้น
ฉันต้องการที่จะเพิ่มในขณะที่มีที่มามันไม่ใช่เรื่องง่าย exitที่สคริปต์จากภายในฟังก์ชั่นโดยไม่ต้องฆ่าเชลล์ ฉันคิดว่าตัวอย่างจะดีกว่าในสคริปต์ 'ทดสอบ'
#!/bin/bash
function die(){
   echo ${1:=Something terrible wrong happen}
   #... clean your trash
   exit 1
}
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"ทำดังต่อไปนี้:
user$ ./test
Whatever is not available
user$test - และ - เชลล์จะปิด
user$ . ./test
Whatever is not availableเท่านั้นtestจะเสร็จสิ้นและจะแจ้งให้
วิธีแก้ไขคือปิดโพรซีเดอร์ใน(และ)
#!/bin/bash
function die(){
   echo $(1:=Something terrible wrong happen)
   #... clean your trash
   exit 1
}
( # added        
    [ -f /whatever/ ] || die "whatever is not available"
    # now we can proceed
    echo "continue"
) # addedตอนนี้ทั้งสองกรณีเท่านั้นที่testจะออก
(และ)วางบล็อกนั้นใน sub-shell โดยไม่ต้องทำ.คำสั่ง (ซอร์ส) อย่างมีประสิทธิภาพเหมือนกับว่าคุณได้รันสคริปต์ทดสอบตามปกติซึ่งอยู่ใน sub-shell ถ้าสคริปต์ไม่ทำงาน.หรือsourceคุณมี 2 sub-shells อย่างมีประสิทธิภาพ
                    คำถามของ OP: อะไรคือความแตกต่างระหว่างคำสั่ง return และ exit ในฟังก์ชั่น BASH ที่เกี่ยวกับรหัสทางออก?
ต้องมีการชี้แจงบางอย่าง:
ในรายการหัวข้อย่อยด้านบนเลือกจาก "(x | y)" ไม่ว่าจะเป็นรายการแรกหรือรายการที่สองเสมอเพื่อรับข้อความเกี่ยวกับฟังก์ชั่น & return หรือ shells & exit ตามลำดับ
สิ่งที่ชัดเจนคือพวกเขาทั้งสองแบ่งปันการใช้งานร่วมกันของตัวแปรพิเศษ $? เพื่อส่งผ่านค่าขึ้นไปหลังจากที่ยุติ
* สำหรับวิธีพิเศษที่ $? สามารถตั้งค่า:
มันเป็นที่น่าสังเกตว่า $? สามารถกำหนดค่าโดยการเรียก exit ใน sub shell เช่นนี้
# (exit 259)
# echo $?
3  exit 259echos 3เพราะค่าทางออกสุดท้ายคือไบต์เดียว  259 % 256 = 3
                    ประการแรกreturnคือคำหลักและexitเพื่อนของฉันคือฟังก์ชั่น
ที่กล่าวว่านี่เป็นคำอธิบายที่ง่ายที่สุด
return 
มันคืนค่าจากฟังก์ชั่น 
exit
ออกจากหรือละทิ้งเชลล์ปัจจุบัน
returnเป็นคำหลัก ผลตอบแทนนั้นเป็นมากกว่าแค่รหัสทางออกซึ่งเป็นเหตุผลที่การเปรียบเทียบไม่ยุติธรรม
                    exitมิได้returnเป็น "คำหลัก" หรือเป็นคู่มือโทรทุบตีพวกเขา "คำสงวน" ไม่มีใครเป็น "ฟังก์ชั่น" อย่างใดอย่างหนึ่งในความหมายของฟังก์ชั่นทุบตี ทั้งคู่เป็นคำสั่งในตัวในภาษา bash lingo (มีเป็นฟังก์ชัน C ห้องสมุดมาตรฐานที่เรียกว่าexit()และการเขียนโปรแกรมภาษา C มีคำสงวนreturnแต่ผู้ที่ไม่ควรจะสับสนกับคำสั่งทุบตีแม้ว่าความหมายของพวกเขามีความคล้ายคลึงซอกแซก.)
                    
help <command>เชลล์ของคุณเพื่อรับข้อมูลว่าเชลล์บิวด์อินจะทำอะไร ในกรณีของคุณhelp returnและhelp exit