shell腳本中使用return和exit的方法
shell腳本之如使用return和exit
return和exit各有用途,合理使用可以使shell編程更規(guī)范可控。
一、exit和return基礎(chǔ)
1、return是一個關(guān)鍵字; exit是一個函數(shù)。
2、return是編程語言級別,它表示調(diào)用堆棧的返回;exit是系統(tǒng)調(diào)用級別,它表示了一個進(jìn)程的結(jié)束。
3、return是函數(shù)的退出(返回);exit是進(jìn)程的退出。
exit 0
正常運(yùn)行程序并退出程序。使用echo $?返回0,也就是說調(diào)用環(huán)境認(rèn)為你的程序執(zhí)行正常。
exit 1
非正常運(yùn)行導(dǎo)致退出程序,也可以是其他數(shù)字,例如exit -1。系統(tǒng)程序?qū)τ诔绦蜻\(yùn)行錯誤是有約定含義的,不為 0 就表示程序運(yùn)行出錯。調(diào)用環(huán)境根據(jù)這個返回值,判斷你的程序運(yùn)行是否正常。
return 0用于函數(shù)中,表示函數(shù)執(zhí)行成功并返回 0;而exit 0 則表示當(dāng)前程序執(zhí)行成功并且直接退出當(dāng)前執(zhí)行腳本或程序。
return -1 表示函數(shù)執(zhí)行失敗返回錯誤;exit 1 (或大于 1)表示程序執(zhí)行失敗并退出程序。
總結(jié): exit用于退出整個shell腳本進(jìn)程。
EXIT退出指令舉例
"exit"命令是終止Bash shell腳本的最常見方法之一。它允許腳本在執(zhí)行過程中的任何時(shí)候退出,并且可以使用可選的退出代碼來表示腳本終止的原因。
# 檢查一個文件是否存在 if [ -f "myfile.txt" ]; then echo "The file exists" exit 0 # 成功的退出 else echo "The file does not exist" exit 1 # 異常的退出并附帶說明 fi
在這個例子中,腳本使用“-f”測試運(yùn)算符檢查一個名為“myfile.txt”的文件是否存在。如果文件存在,腳本會向控制臺打印一條消息,并使用“exit”命令以成功代碼0退出。如果文件不存在,腳本會打印不同的消息,并使用錯誤代碼1退出。
“exit”命令還可以用于處理腳本執(zhí)行過程中的錯誤或意外情況。例如,假設(shè)一個腳本需要訪問可能不可用的資源,如網(wǎng)絡(luò)服務(wù)或數(shù)據(jù)庫。在這種情況下,腳本可以使用“exit”命令以錯誤消息和適當(dāng)?shù)耐顺龃a優(yōu)雅地終止。
在函數(shù)中使用return語句退出舉例
#!/bin/bash # 定義一個函數(shù)并返回?cái)?shù)字之和 function add_numbers { local num1=$1 local num2=$2 local sum=$((num1 + num2)) return $sum } # 調(diào)用函數(shù)并打印結(jié)果 read_file "myfile.txt" # 調(diào)用函數(shù)并打印結(jié)果 add_numbers 3 71 result=$? echo "3 + 71 = $result"
在這個例子中,腳本定義了一個名為“add_numbers”的函數(shù),它接受兩個參數(shù)并返回它們的總和。在函數(shù)內(nèi)部,使用“return”命令以總和作為返回值退出。
**“return”命令也可以用于處理函數(shù)內(nèi)部的錯誤或意外情況。**例如,假設(shè)一個函數(shù)需要從一個文件中讀取數(shù)據(jù),但是該文件不存在。在這種情況下,函數(shù)可以使用“return”命令以錯誤代碼和錯誤消息退出。
#!/bin/bash # 定義一個函數(shù)讀取文件 function read_file { local file=$1 if [ ! -f "$file" ]; then echo "Error: File $file not found" return 1 fi cat $file }
如果文件不存在,函數(shù)將打印一個錯誤消息并返回錯誤代碼1,該代碼可以由調(diào)用腳本或進(jìn)程用于相應(yīng)地處理錯誤。
**在函數(shù)內(nèi)使用“return”命令是一個很好的方式,可以正確退出函數(shù)并將其結(jié)果傳達(dá)給腳本的其他部分或調(diào)用進(jìn)程。**通過使用適當(dāng)?shù)姆祷刂岛湾e誤代碼,腳本可以處理意外情況,并提高其整體穩(wěn)健性和可靠性。
二、最佳實(shí)踐
- 函數(shù)必須使用return退出,不能用exit。
- 腳本主體邏輯使用return設(shè)置退出碼,最后用exit退出腳本。
- 如果需要精確控制退出碼,腳本中的各處邏輯都建議用return。
- 發(fā)生不可處理的錯誤時(shí),可以直接用exit終止腳本。
三、子腳本返回非零狀態(tài)碼時(shí)導(dǎo)致主控腳本退出中斷的問題
問題描述
主控腳本A,循環(huán)調(diào)用子腳本B、C,執(zhí)行B子腳本exit,發(fā)現(xiàn)主控腳本A循環(huán)中斷了,C子腳本沒有調(diào)用
[重要]問題分析
開始以為:exit 會導(dǎo)致整個腳本進(jìn)程結(jié)束,主控制腳本循環(huán)也會被中斷。測試發(fā)現(xiàn)子腳本 exit非零,會導(dǎo)致主控腳本也直接退出
其實(shí)最后發(fā)現(xiàn),是我主控日志打印,根據(jù)子腳本的 $? 結(jié)果,非0時(shí)自己exit 的,并不是因?yàn)樽幽_本非0 exit,主控就一定退出!??! 是一場烏龍~
結(jié)論:子腳本的exit不會直接導(dǎo)致主腳本退出,主程序要自行處理$?并決定下一步操作。
不過可以這里總結(jié)出如下2個比較有用的shell實(shí)踐技巧:
- 善用exit $?
- 使用 sh 調(diào)子腳本
使用函數(shù)+return 方式返回狀態(tài)碼,最后 exit $? 方式退出腳本
完整示例demo:
start_mongodb(){ $MONGODB_BIN_DIR/mongod -f $MONGO_CONF if [ $? -eq 0 ]; then echo "MongoDB started successfully" return 0 else echo "Failed to start MongoDB" return 1 fi } stop_mongodb(){ $MONGODB_BIN_DIR/mongod -f $MONGO_CONF --shutdown if [ $? -eq 0 ]; then echo "MongoDB stopped successfully" return 0 else echo "Failed to stop MongoDB" return 1 fi } status(){ if [ -f $MONGODB_PIDFILE ]; then echo "MongoDB is running, PID: $(cat $MONGODB_PIDFILE)" return 0 else echo "MongoDB is stopped" return 1 fi } function control_mongodb(){ case $1 in start) start_mongodb ;; stop) stop_mongodb ;; restart) stop_mongodb start_mongodb ;; status) status ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 esac return $? } # 調(diào)用函數(shù) control_mongodb $1 exit $?
在Linux shell腳本中,exit $? 表示使用上一個命令的退出狀態(tài)碼來退出當(dāng)前shell腳本。$? 是一個特殊變量,它保存了上一個執(zhí)行的命令或者函數(shù)的退出狀態(tài)碼。退出狀態(tài)碼0表示成功執(zhí)行,非0通常表示失敗或錯誤。exit $? 的具體作用是:
- $? 獲取上一個命令的退出碼
- exit 使腳本退出
- 將上一個命令的退出碼作為腳本的最終退出碼
使用 sh 調(diào)子腳本,需要注意事項(xiàng)
使用 sh 調(diào)子腳本,通常有下面的幾種使用場景:
強(qiáng)制子腳本在一個干凈的環(huán)境中運(yùn)行。
sh
會啟動一個新的shell實(shí)例,不會繼承當(dāng)前shell的任何自定義設(shè)置、變量等,可以提供一個干凈隔離的運(yùn)行環(huán)境。- 為子腳本設(shè)置特定的shell。直接調(diào)用子腳本時(shí),使用當(dāng)前shell(通常是bash),但有時(shí)需要指定為sh、csh等其他shell。
- 在腳本中改變目錄時(shí),調(diào)用子腳本使用相對路徑。
sh
重置了工作目錄,使相對路徑生效。- 當(dāng)子腳本需要另一個版本的shell時(shí)。直接調(diào)用繼承當(dāng)前shell,但 sh 可以指定所需的shell。
- 在升級系統(tǒng)shell時(shí),保證子腳本向后兼容。直接調(diào)用使用新shell可能出錯,但 sh 調(diào)用可保持原有的shell。
- 出于安全考慮,不信任子腳本,使用 sh 加沙箱隔離。
- 在守護(hù)進(jìn)程中調(diào)用腳本,需要一個干凈可預(yù)測的新shell環(huán)境。一些老的腳本依賴 sh 調(diào)用,直接轉(zhuǎn)換會破壞原有行為。
總之,使用 sh 調(diào)用主要是為了精細(xì)控制子腳本的執(zhí)行環(huán)境,符合特定的兼容性要求等。但通常需要時(shí),直接調(diào)用更簡單。
其實(shí)一般情況下,不推薦使用 sh,因?yàn)橛袝r(shí)通過sh 調(diào)子腳本會有問題,例如:sh 執(zhí)行腳本時(shí), kill 命令出現(xiàn)了非法選項(xiàng)的錯誤
dash 和 bash 在處理 kill 命令選項(xiàng)上有一些細(xì)微區(qū)別。dash 不支持不帶參數(shù)的 kill 命令,也不支持kill -s 信號的方式,需要直接寫信號名。所以在 bash 下可以正常執(zhí)行:
kill -SIGTERM pid kill -s TERM pid
但在 dash 下,需要寫成:
kill -TERM pid
你的腳本本身沒有問題,但當(dāng)通過 sh 調(diào)用時(shí),使用了 dash 的限制導(dǎo)致了錯誤。可以修改為直接調(diào)用腳本,不使用 sh:
./nginx_ctrl.sh stop
或者在腳本中用 kill -TERM 替代 kill -s TERM。這種 shell 的差異導(dǎo)致的錯誤可以引起注意,如果兼容 sh/dash 也需要調(diào)整下參數(shù)格式。
你可以通過以下幾種方法來判斷系統(tǒng)默認(rèn)的 sh 是什么 shell:
1.直接運(yùn)行 sh,看看默認(rèn)進(jìn)入的是什么 shell:
$ sh $ echo $SHELL /bin/dash
如果打印出來是 /bin/dash,那么默認(rèn)就是 dash。
2. 查看 /bin/sh 的符號鏈接所指向的文件:
$ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Mar 15 2020 /bin/sh -> dash
如果是指向 dash 就表示默認(rèn)是 dash。
Ubuntu 和 Debian 默認(rèn)就是 dash。
到此這篇關(guān)于shell腳本之如使用return和exit的文章就介紹到這了,更多相關(guān)shell使用return和exit內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Linux 通過 autojump 命令減少 cd 命令的使用的實(shí)現(xiàn)方法
這篇文章主要介紹了Linux 通過 autojump 命令減少 cd 命令的使用的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Shell腳本導(dǎo)入導(dǎo)出數(shù)據(jù)的項(xiàng)目示例
在工作中,很多場景都會涉及到數(shù)據(jù)的導(dǎo)入導(dǎo)出,本文就介紹一下使用Shell腳本導(dǎo)入導(dǎo)出數(shù)據(jù)的項(xiàng)目示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Shell腳本中執(zhí)行sql語句操作mysql的5種方法
這篇文章主要介紹了Shell腳本中執(zhí)行sql語句操作mysql的5種方法,本文講解了將SQL語句直接嵌入到shell腳本文件中、命令行調(diào)用單獨(dú)的SQL文件、使用管道符調(diào)用SQL文件等方法,需要的朋友可以參考下2014-10-10Shell腳本判斷進(jìn)程是否存在的實(shí)現(xiàn)示例
本文主要介紹了Shell腳本判斷進(jìn)程是否存在的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06shell腳本中一鍵部署zookeeper集群服務(wù)的方法
Zookeeper是一個開源的分布式的,為分布式框架提供協(xié)調(diào)服務(wù)的Apache項(xiàng)目,這篇文章主要介紹了shell腳本一鍵部署zookeeper集群服務(wù)的方法,需要的朋友可以參考下2022-05-05