Shell指令碼中參數傳遞方法常用有8種
1. $# 傳遞到指令碼的參數個數
2. $* 以一個單字串顯示所有向指令碼傳遞的參數變數。與位置變數不同,此選項參數可超過9個
3. $$ 指令碼啟動並執行當前進程ID號
4. $! 後台啟動並執行最後一個進程的進程ID號
5. $@ 與$#相同,但是使用時加引號,並在引號中返回每個參數
6. $- 顯示shell使用的當前選項,與set命令功能相同
7. $? 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤
8. $()裡面放命令,可以在指令碼中執行該命令,並返回命令執行的輸出
下面給各位深入分析
1、命令列參數
向shell指令碼傳遞資料的最基本方式是使用命令列參數。
(1) 讀取參數
讀取輸入的參數的變數為位置參數,位置參數通過標準數字表示,
其中$0為程式名稱,$1為第一個參數,$2為第二個參數,依次類推,直到$9為第九個參數。
shell指令碼自動將命令列參數賦值給各個位置變數。
同時輸入多個參數(可以是數值也可以是字串)時,必須使用空 格分隔(要想在參數值中包含空格,就必須使用單引號或雙引號)
當參數多於9個後,必須在shell指令碼內使用大括弧將變數括起來,如${10}。從而可以使用任意個參數。
(2)讀取程式名稱
傳遞給變數$0的字串實際上是程式的路徑(根據調用方法決定是相對還是絕對路徑)。
使用basename命令可以去掉路徑首碼,只獲得程式名稱(名字中不 可以有空格)。
(3)測試指令碼
當指令碼認為應該包含參數,卻實際上沒有資料時,就會出錯。
好的方法是 對參數進行檢查來保證使用參數前確實存在資料,可以使用-n參數來檢查。
ex: if [ –n “$1” ] then .. else .. fi
2、特殊的參數變數
用於跟蹤命令列參數
(1)參數計數
使用特殊變數$#測試執行指令碼時包含的命令列參 數個數。指令碼中任何位置都可以使用$#
ex: if [ $# –ne 2 ] 即可測試參數個數
可 以使用${!#}來返回最後一個命令列參數(當無參數時,$#為0, 而${!#}為程式名)
(2)擷取所有資料
變數$*將命令列中提供的所有參數作為一個單詞處理,它將多個參數看成 一個參數。
變數$@將命令列中提供的所 有參數作為同一個字串中的多個單詞處理。允許對其中的值進行迭代(一般使用for),分隔開不同參數
3、 移位
shift命 令能夠改變命令列參數的相對位置。預設將每個參數變數左移一個位置(變數$0不變,把$1丟棄,注意 不可以恢複了!)
在不清楚參數數目情況下,這是一個迭代參數的好辦法。
可 以為shift提供一個參數,來實現多位移變化。
4、處理選項
選項是由破折號 引導的單個字母,用於更改命令的行為。
(1)找出選項
1)處理簡單選項
可以使用處理命令列參數相同的方法處理選項,抽取時使用case 語句進行判斷是否符合選項格式。
2)從參數中分離選項
同 時使用選項和參數時,可以使用--指示選項列表的結束。發現--後,shell就知道後面的是普通參數了,停止使用case處理選項。
3) 處理帶值的選項
選項後緊跟參數值,一種方法是在case中對應選項後使用shift和讀後一位參數的 方法處理。更好的方法如下:
(2)使用getopt命 令
getopt命令在處理選項和參數時 非常方便。它對參數進行重新組織,以便於解析
1)命令格式
getopt可以接受任意 形式的選項和參數列表,並自動將它們轉換為適當的格式。
命令格式為: getopt options optstring parameters
選項字串(opstring)用於定義命令列 中的有效選項字母,以及哪些選項字母需要參數值。
2)指令碼中使用getopt
需要使用set命令將現有的 命令列選項和參數替換為getopt命令產生的格式化形式。
需要將原始指令碼命令行參數送給getopt命令,然後將 getopt命令輸出送給set命令,如下:set – `getopts –q ab:cd “$@”`
但 是getopt命令不能很好的處理帶有空格的參數值,它將空格解析為參數分隔字元,而不是將雙引號引起來的兩個值合并成一個參數。解決辦 法如下:
(3)更進階的getopts命令
getopts命令順序的對現有的shell參數變數進行處理, 每調用一次,只處理命令中檢測到的參數中的一個。處理完所有參數後,以大於0的退出狀態退出。
非常適宜於在迴圈中解析所 有命令列參數
格式為: getopts optstring variable
$OPTARG包含需 要參數值的選項要使用的值,$OPTIND包含getopts停止處理時在參數列表中的位置。
注意:當getopts處 理時,會將選項前的-去掉,所以對應的case中不需要破折號。
好的特性:
1)可以在參數值中包含空 格
2)選項字母和參數值中間可以沒有空格
3)將在命令列中找到的未定義的選項都綁定為單一的輸出——問號
5、標準化選項
有一些字母選項具有標準含義。最好按照標準含義定義選項意義
-a –c –d –e –f –h –i –l –n –o –q –r –s –v- x –y
6、擷取使用者輸入
當需要在執 行過程中獲得執行指令碼人員的輸入,使用read命 令
(1)基本讀取
read命 令接受標準輸入或其他檔案描述符輸入。讀入後將資料放入一個標準變數中。
-p 允許在read命令列中直接指定一個提示。
可以指定多個變數,也可以不指定(將放置在REPLY環境變數中)
(2)計 時
使用-t指定一個計時器,計時數滿還未輸入,read返回一個非0的退出狀態。
使 用-n指定輸入的字元個數,輸入達到預定數目時,就自動結束輸入
(3)默讀
使用 -s使輸入不顯示在終端(例如輸入密碼)
(4)讀取檔案
最常用的方法是使用cat命令,並通過管 道傳給包含read的while語句。
ex: cat test | while read line
為了讓各位更多深入瞭解給一些例子
#!/bin/bash
#extracting command text_text_text_line options as parameters
help_info(){
echo "NAME"
echo "\t$0"
echo "SYNOPSIS"
echo "\t$0 is a shell test about process options"
echo "DESCRIPTION"
echo "\toption like -a -b param1 -c param2 -d"
}
if [ $# -lt 0 ]
then
help_info
fi
nomal_opts_act()
{
echo -e "\n### nomal_opts_act ###\n"
while [ -n "$1" ]
do
case "$1" in
-a)
echo "Found the -a option"
;;
-b)
echo "Found the -b option"
echo "The parameter follow -b is $2"
shift
;;
-c)
echo "Found the -c option"
echo "The parameter follow -c is $2"
shift
;;
-d)
echo "Found the -d option"
;;
*)
echo "$1 is not an option"
;;
esac
shift
done
}
#用shell命令自建的選項解析,可以按照自己的想法實現
#優點:自己定製,沒有做不到,只有想不到
#缺點:麻煩
getopt_act()
{
echo -e "\n### getopt_act ###\n"
GETOPTOUT=`getopt ab:c:d "$@"`
set -- $GETOPTOUT
while [ -n "$1" ]
do
case $1 in
-a)
echo "Found the -a option"
;;
-b)
echo "Found the -b option"
echo "The parameter follow -b is "$2""
shift
;;
-c)
echo "Found the -c option"
echo "The parameter follow -c is "$2""
shift
;;
-d)
echo "Found the -d option"
;;
--)
shift
break
;;
*)
echo "Unknow option: "$1""
;;
esac
shift
done
param_index=1
for param in "$@"
do
echo "Parameter $param_index:$param"
param_index=$[ $param_index + 1 ]
done
}
#用getopt命令解析選項和參數
#優點:相對與getopts來說是個半自動解析,自動組織選項和參數,用 -- 符號將選項與參數隔開
#缺點:相對於getopts的缺點
#1.需要與set -- 命令配合,不是必須,需要手動shift
#2.選項參數中不支援空格如 -a -b dog -c "earth moon" -d -f param1 param2 就會解析錯誤
getopts_act()
{
echo -e "\n### getopts_act ###\n"
while getopts :ab:c:d ARGS
do
case $ARGS in
a)
echo "Found the -a option"
;;
b)
echo "Found the -b option"
echo "The parameter follow -b is $OPTARG"
;;
c)
echo "Found the -c option"
echo "The parameter follow -c is $OPTARG"
;;
d)
echo "Found the -d option"
;;
*)
echo "Unknow option: $ARGS"
;;
esac
done
shift $[ $OPTIND -1 ]
param_index=1
for param in "$@"
do
echo "Parameter $param_index:$param"
param_index=$[ $param_index + 1 ]
done
}
#getopts 命令解析選項和參數
#優點:可在參數中包含空格如:-c "earth moon"
# 選項字母和參數值之間可以沒有空格如:-bdog
# 可將未定義的選項綁定到?輸出
# Unknow option: ?
nomal_opts_act -a -b dog -c earth -d -f param1 param2
getopts_act -a -b dog -c "earth moon" -d -f param1 param2
getopt_act -a -b dog -c earth -d -f param1 param2