อะไรคือความแตกต่างระหว่างคำสั่ง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 function
exit
จะมีฟังก์ชั่นไม่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 259
echos 3
เพราะค่าทางออกสุดท้ายคือไบต์เดียว 259 % 256 = 3
ประการแรกreturn
คือคำหลักและexit
เพื่อนของฉันคือฟังก์ชั่น
ที่กล่าวว่านี่เป็นคำอธิบายที่ง่ายที่สุด
return
มันคืนค่าจากฟังก์ชั่น
exit
ออกจากหรือละทิ้งเชลล์ปัจจุบัน
return
เป็นคำหลัก ผลตอบแทนนั้นเป็นมากกว่าแค่รหัสทางออกซึ่งเป็นเหตุผลที่การเปรียบเทียบไม่ยุติธรรม
exit
มิได้return
เป็น "คำหลัก" หรือเป็นคู่มือโทรทุบตีพวกเขา "คำสงวน" ไม่มีใครเป็น "ฟังก์ชั่น" อย่างใดอย่างหนึ่งในความหมายของฟังก์ชั่นทุบตี ทั้งคู่เป็นคำสั่งในตัวในภาษา bash lingo (มีเป็นฟังก์ชัน C ห้องสมุดมาตรฐานที่เรียกว่าexit()
และการเขียนโปรแกรมภาษา C มีคำสงวนreturn
แต่ผู้ที่ไม่ควรจะสับสนกับคำสั่งทุบตีแม้ว่าความหมายของพวกเขามีความคล้ายคลึงซอกแซก.)
help <command>
เชลล์ของคุณเพื่อรับข้อมูลว่าเชลล์บิวด์อินจะทำอะไร ในกรณีของคุณhelp return
และhelp exit