shell指令碼中main函式中$#獲取不到指令碼傳入引數個數淺析

潇湘隐者發表於2024-03-14

Linux的shell指令碼,有時候我們在執行shell指令碼時會給指令碼傳入引數,出於邏輯上的嚴謹,在指令碼中可能會做一些邏輯判斷或處理,例如判斷指令碼傳入引數的個數。一般我們會用$#獲取傳入引數的個數,假如,我們在shell指令碼的main函式中去判斷指令碼傳入引數的個數,類似如下所示:

.........
function main()
{
if [ $# != 1 ]; then
echo "This script must be run with one parameter"
echo "Usage:mysql_slowlog_monitor.sh 6h"
exit 1
fi

check_enviroment;
send_slow_rpt;
return 0;
}

main;

如果你去除錯這個shell指令碼的話,就會發現main函式中$#的值永遠是0, 如果將指令碼調整一下,將判斷傳入引數個數的指令碼放到main函式外(不能放在其它函式中),如下所示,這樣就Ok了

.............

if [ $# != 1 ]; then
echo "This script must be run with one parameter"
echo "Usage:mysql_slowlog_monitor.sh 6h"
exit 1
fi

.............
function main()
{
check_enviroment;
send_slow_rpt;
return 0;
}

main;

那麼為什麼會出現這種情況呢?在解答這個問題前,我們先來了解一下$#的用途,$#表示指令碼傳入引數的個數,也表示一個函式(function)呼叫時,傳入函式的引數(arguments)個數,而且它也是有作用域範圍,如果在函式(function)內部的話,它表示的函式呼叫時,傳入引數的個數。

那麼再來解答這個問題,上面shell指令碼中,main函式呼叫時寫法為main;意味著函式呼叫時沒有傳入任何引數,所以$#在main中值為0,而在指令碼mysql_slowlog_monitor.sh中獲取傳入的引數個數,應該在指令碼中,而且在指令碼中的函式外面獲取它的值。

那麼怎麼解決這個問題呢?

解決方案1:

將判斷指令碼呼叫時傳入的引數的指令碼放到函式外面,就像上面示例指令碼那樣處理。

解決方案2:

藉助全域性變數,先在函式外獲取指令碼傳入引數的個數,將其賦值為全域性變數,然後在mian函式中,進行邏輯判斷和處理。

.............
ARGS=$#
.............
function main()
{
if [ $ARGS != 1 ]; then
echo "This script must be run with one parameter"
echo "Usage:mysql_slowlog_monitor.sh 6h"
exit 1
fi
check_enviroment;
send_slow_rpt;
return 0;
}

main;

相關文章