歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> SHELL編程 >> 使用getopts處理shell中的輸入參數

使用getopts處理shell中的輸入參數

日期:2017/3/1 9:15:07   编辑:SHELL編程

在編寫shell腳本中,經常要處理一些輸入參數,在使用過程中發現getopts更加方便,能夠很好的處理用戶輸入的參數和參數值。

getopts用於處理用戶輸入參數,舉例說明使用方法:

while getopts :a:b:cdefg opt; do

case $opts in

a) do sth;

......

cde) do another;

esac

done

幾個重要變量:

OPTIND:getopts使用OPTIND作為索引,來處理下一個需要處理的參數,記錄當前的狀態。

OPTARG:在上面的循環中,a,b兩個參數後面各有一個冒號,冒號表示該輸入的參數後面還有一個參數值,當getopts發現冒號後,會處理用戶輸入的參數值,這個參數值被保存在OPTARG中。

OPTSTRING:也就是上例中的 :a:b:cdefg,getopts需要處理的參數。注意,最前面的冒號“:”用於指定getopts工作於silent mode,在silent模式下,當用戶輸入的參數不滿足OPTSTRING時,不會講illegal option這樣的錯誤信息打印出來,使代碼看起來更加專業。如果想要工作在verbose模式下,可以去掉最前面的冒號

下面,簡單的寫了一個shell腳本用來描述getopts的使用方法:

#! /bin/bash
function c1() {
cmd="rhc app create -p RedHat"
while getopts :a:t:sn opt; do
case $opt in
a) cmd=$cmd" -a $OPTARG" ;;
t) cmd=$cmd" -t $OPTARG" ;;
s) cmd=$cmd" -s" ;;
n) cmd=$cmd" -n --no-dns" ;;
\?) echo "Invalid param" ;;
esac
done
echo $cmd
}

c1 -a app1 -t perl-5.10 -s -n

執行這個腳本,我們就會得到預期的結果

[root@linuxidc shell]# ./getopts-silent.sh
rhc app create -p redhat -a app1 -t perl-5.10 -s -n --no-dns

當然,有些時候,我們更新網將function寫入.bashrc中,方便自己隨時調用,如果將這段代碼直接粘貼到.bashrc中,可能會引起問題:我沒有得到預期的結果,腳本中的cmd並沒有按照預想的情況得到處理,這是因為什麼呢?

原因在於,保存在.bashrc後,第一次執行完成後,下一次在執行時,OPTIND不會重新產生,因為他被作為一個global variable使用,所以getopts在調用時,他的索引會變得混亂。在腳本中執行沒有遇到這個問題的原因也在此,因為腳本每次執行時,都會調用一個 新的shell,所以OPTIND會被設置為1。如果想要他在.bashrc中生效,必須要在最上面加上local OPTIND

讓我們來稍微修改一下:



# Create apps
function create-apps() {
local OPTIND
cmd="rhc app create -p $OPENSHIFT_PASSWD"
while getopts a:t:sn x
do
case $x in
a) cmd=$cmd" -a $OPTARG" ;;
t) cmd=$cmd" -t $OPTARG" ;;
s) cmd=$cmd" -s" ;;
n) cmd=$cmd" -n --no-dns" ;;
\?) echo Invalid Params ;;
esac
done
echo $cmd
}

source之後,我們可以直接調用,看一下是否達到了我們預期的結果:

[root@linuxidc shell]# create-apps -a free -t jbsseap -n
rhc app create -p redhat -a free -t jbsseap -n --no-dns

如果還不是很了解,你可以簡單的看下這個例子,這個例子是如果傳遞進來的參數包括f,那麼執行對應代碼:

while getopts "dfiPRrvW" opt //賦值給opt
do
case $opt in
f) //如果傳遞進來是f
exec $realrm "$@"
;;
*)

# do nothing //傳遞其他參數,包括d,i,p,r,v,w
;;
esac
done

Copyright © Linux教程網 All Rights Reserved