Shell傳參快速使用腳本
- 簡便版
input="$1"
echo ${input}
- 進階版
getopt方法
ARGS=$(getopt -a -o i:t::h -l input:,test::,help -- "$@")
eval set -- "${ARGS}"
#help function
function usage() {
echo -e "OPTIONS:\n-i|--input:\t input value"
echo -e "-t|--test:\t Test value"
echo -e "-h|--help:\t Usage information"
echo -e "-o|--output:\t Output value"
exit 1
}
#get value
while true
do
case "$1" in
-i|--input)
input="$2"
shift
;;
-t|--test)
test="$2"
;;
-o|--output)
output="true"
;;
-h|--help)
usage
;;
--)
shift
echo -e "\nUnused option(s): $@"
break
;;
esac
shift
done
#default value
test=${test:="test0"}
output=${output:="false"}
echo 'Input value:'$input
echo 'Test value:'$test
echo 'Output value:'$output
getopts方法
#default value
input='0'
test=${test:="test0"}
output=${output:="false"}
#help function
function usage() {
echo -e "OPTIONS:\n-i|--input:\t input value"
echo -e "-t|--test:\t Test value"
echo -e "-h|--help:\t Usage information"
echo -e "-o|--output:\t Output value"
exit 1
}
#get value
while getopts :i:t::ho opt
do
case "$opt" in
i) input="$OPTARG" ;;
t) test="$OPTARG" ;;
h) usage ;;
o) output="true" ;;
:) echo "This option -$OPTARG requires an argument."
exit 1 ;;
?) echo "-$OPTARG is not an option"
exit 2 ;;
esac
done
echo 'Input value:'$input
echo 'Test value:'$test
echo 'Output value:'$output
做生信一般都繞不開Shell腳本編寫,如果腳本可以傳參就能實現(xiàn)大批量任務(wù)投遞饰剥,而且也可以通過傳參把相關(guān)流程封裝起來忠荞,相當(dāng)于與一個包或模塊蒋歌,用起來也比較方便。然而Shell腳本又不像R和Python等語言委煤,有現(xiàn)成包或模塊可以簡單快速實現(xiàn)傳參(我之前寫了R語言和Python傳參的文章堂油,感興趣可以點進去看一下。)碧绞,不過其實Shell傳參也沒有特別復(fù)雜府框,簡單學(xué)習(xí)一下也能快速上手。最簡單的傳參就是使用$1头遭,$2這種形式寓免,分別代表第一個和第二個參數(shù),但是如果參數(shù)多起來就不太方便了计维,還是有名字的參數(shù)比較方便袜香。
getopt與getopts簡介
getopt和getopts都是Shell自帶的命令行參數(shù)解析工具,應(yīng)該就類似于awk和sed工具鲫惶,但兩者用法稍有不同蜈首,前者能實現(xiàn)更多功能,例如支持長名稱欠母,而后者不支持欢策,但getopts使用起來稍微簡單些,不用使用shift命令赏淌,更詳細的內(nèi)容看一查看這篇博客踩寇。
getopt傳參
getopt可以在命令行直接使用
getopt --alternative a: -a test
--alternative表示允許長名稱,可簡寫為-a六水,--option(-o)后面接短名稱俺孙,--long(-l)后面接長名稱。短名稱由單個字母和0-2個冒號組成掷贾,例如i睛榄,i:,i::想帅,如果只有冒號沒有字母场靴,表示如果不指定選項傳參的情況出現(xiàn),忽略錯誤,短名稱與冒號組合后直接寫到一起旨剥,例如i:t::ho咧欣,對應(yīng)的長名稱要按順序并且冒號數(shù)目要對應(yīng),并以逗號分隔泞边。--表示后面的內(nèi)容都會視為一個輸入?yún)?shù)该押。
- 參數(shù)后面冒號個數(shù)的含義:0個表示不接受參數(shù),1個表示必須接受參數(shù)阵谚,2個表示可接也可不接受參數(shù)蚕礼。注意2個冒號的可選參數(shù)如果要傳參需要寫成-ttest形式,寫成-t test或-t=test都不行梢什。
在腳本中使用getopt
- 第一步奠蹬,首先,構(gòu)建參數(shù)變量嗡午,使用getopt先定義參數(shù)囤躁,然后獲取外部參數(shù)數(shù)組傳給變量ARGS。$@表示傳入的所有參數(shù)荔睹。
ARGS=$(getopt --alternative --option :i:t::ho --long :input:,test::,help,output -- "$@")
eval set -- "${ARGS}"
set命令可以模擬傳參過程狸演,用法是set -- $(getopt a "$@"),相當(dāng)于把getopt從命令行獲取產(chǎn)出處理后的結(jié)果傳給set僻他,但由于是二次處理的參數(shù)結(jié)果宵距,如果出現(xiàn)復(fù)雜的參數(shù)(例如有空格的參數(shù))就會出現(xiàn)問題,因此需要eval命令把后面的內(nèi)容作為單個命令讀取和執(zhí)行吨拗。
- 第二步满哪,構(gòu)建幫助信息函數(shù)
function usage() {
echo -e "OPTIONS:\n-i|--input:\t input value"
echo -e "-t|--test:\t Test value"
echo -e "-h|--help:\t Usage information"
echo -e "-o|--output:\t Output value"
exit 1
}
-
第三步,獲取參數(shù)值
shift命令可以把第一個參數(shù)去電劝篷,使得第二個參數(shù)變成第一個參數(shù)哨鸭,以此類推。因此娇妓,可以通過shift函數(shù)結(jié)合while循環(huán)逐個獲取參數(shù)像鸡。
while true
do
case "$1" in
-i|--input)
input="$2"
shift
;;
-t|--test)
test="$2"
;;
-o|--output)
output="true"
;;
-h|--help)
usage
;;
--)
shift
echo -e "\nUnused option(s): $@"
break
;;
esac
shift
done
-
第四步,設(shè)置默認值
這里的邏輯是先檢測變量是否為空哈恰,如果為空則賦默認值坟桅,使用:=實現(xiàn)給變量設(shè)置默認值可以查看這篇博客。
當(dāng)然蕊蝗,其實也可以先在上述循環(huán)前直接給變量賦值。
test=${test:="test0"}
output=${output:="false"}
示例1
test.sh內(nèi)容
ARGS=$(getopt --alternative --option :i:t::ho --long :input:,test::,help,output -- "$@")
#ARGS=$(getopt -a -o i:t::h -l input:,test::,help -- "$@")
eval set -- "${ARGS}"
function usage() {
echo -e "OPTIONS:\n-i|--input:\t input value"
echo -e "-t|--test:\t Test value"
echo -e "-h|--help:\t Usage information"
echo -e "-o|--output:\t Output value"
exit 1
}
while true
do
case "$1" in
-i|--input)
input="$2"
shift
;;
-t|--test)
test="$2"
;;
-o|--output)
output="true"
;;
-h|--help)
usage
;;
--)
shift
echo -e "\nUnused option(s): $@"
break
;;
esac
shift
done
test=${test:="test0"}
output=${output:="false"}
echo 'Input value:'$input
echo 'Test value:'$test
echo 'Output value:'$output
運行腳本
~ $ sh test.sh -h
OPTIONS:
-i|--input: input value
-t|--test: Test value
-h|--help: Usage information
-o|--output: Output value
~ $ sh test.sh -i 1
Unused option(s):
Input value:1
Test value:test0
Output value:false
~ $ sh test.sh -i 1 -ttest1
Unused option(s):
Input value:1
Test value:test1
Output value:false
getopts傳參
getopts只支持短名稱選項赖舟,但不需要額外的命令操作就能獲取參數(shù)蓬戚,其涉及3個變量:
OPTIND: 存放下一個要處理的參數(shù)的索引。這是 getopts 在調(diào)用過程中記住自己狀態(tài)的方式宾抓。
OPTARG: 由 getopts 找到的選項所對應(yīng)的參數(shù)子漩。
OPTERR: 值為0或1豫喧。指示Bash是否應(yīng)該顯示由 getopts 產(chǎn)生的錯誤信息。
其它步驟與上述內(nèi)容相同幢泼,只有解析參數(shù)的循環(huán)不一樣紧显,相較而言簡單很多,不用使用shift缕棵,而是直接使用變量OPTARG孵班。
while getopts :i:t::ho opt
do
case "$opt" in
i) input="$OPTARG" ;;
t) test="$OPTARG" ;;
h) usage ;;
o) output="true" ;;
:) echo "This option -$OPTARG requires an argument."
exit 1 ;;
?) echo "-$OPTARG is not an option"
exit 2 ;;
esac
done
示例2
test1.sh內(nèi)容
input='0'
test=${test:="test0"}
output=${output:="false"}
function usage() {
echo -e "OPTIONS:\n-i|--input:\t input value"
echo -e "-t|--test:\t Test value"
echo -e "-h|--help:\t Usage information"
echo -e "-o|--output:\t Output value"
exit 1
}
while getopts :i:t::ho opt
do
case "$opt" in
i) input="$OPTARG" ;;
t) test="$OPTARG" ;;
h) usage ;;
o) output="true" ;;
:) echo "This option -$OPTARG requires an argument."
exit 1 ;;
?) echo "-$OPTARG is not an option"
exit 2 ;;
esac
done
echo 'Input value:'$input
echo 'Test value:'$test
echo 'Output value:'$output
運行腳本
~ $ sh test1.sh -h
OPTIONS:
-i|--input: input value
-t|--test: Test value
-h|--help: Usage information
-o|--output: Output value
~ $ sh test1.sh -i 1
Input value:1
Test value:test0
Output value:false
~ $ sh test1.sh -i 1 -ttest1 -o
Input value:1
Test value:test1
Output value:true