天天看點

Bash Getopts - 讓你的腳本支援指令行參數Bash Getopts - 讓你的腳本支援指令行參數

以前我總想知道如何為我的bash腳本建立指令行參數。經過搜尋,我發現了2個函數可以處理這個問題,getopt 函數和 getopts 函數。我無意争論哪一個函數更好的。getopts 是一個shell内建指令,而且似乎比 getopt 更容易實作這個功能,是以在這篇文章裡我準備講講getopts。

Bash Getopts - 讓你的腳本支援指令行參數Bash Getopts - 讓你的腳本支援指令行參數

<a target="_blank"></a>

開始的時候,我隻試着處理傳遞給腳本的指令行參數。最後,我添加了另外一些有用的功能函數,使得這個腳本可以成為其他任何互動式腳本處理指令行的開始模闆。我還添加了一個純文字格式的幫助函數,讓腳本更加容易閱讀。

與其來一長段文字解釋 getopts 在bash中是如何工作的,我認為不如直接來一個能工作的腳本更讓人覺得輕松一些。

#!/bin/bash

######################################################################

#this is an example of using getopts in bash. it also contains some

#other bits of code i find useful.

#author: linerd

#website: http://tuxtweaks.com/

#copyright 2014

#license: creative commons attribution-sharealike 4.0

#http://creativecommons.org/licenses/by-sa/4.0/legalcode

#set script name variable

script=`basename ${bash_source[0]}`

#initialize variables to default values.

opt_a=a

opt_b=b

opt_c=c

opt_d=d

#set fonts for help.[譯注: 這裡tput用來更改終端文本屬性,比如加粗,高亮等]

norm=`tput sgr0`

bold=`tput bold`

rev=`tput smso`

#help function

function help {

echo -e \\n"help documentation for ${bold}${script}.${norm}"\\n

echo -e "${rev}basic usage:${norm} ${bold}$script file.ext${norm}"\\n

echo "command line switches are optional. the following switches are recognized."

echo "${rev}-a${norm} --sets the value for option ${bold}a${norm}. default is ${bold}a${norm}."

echo "${rev}-b${norm} --sets the value for option ${bold}b${norm}. default is ${bold}b${norm}."

echo "${rev}-c${norm} --sets the value for option ${bold}c${norm}. default is ${bold}c${norm}."

echo "${rev}-d${norm} --sets the value for option ${bold}d${norm}. default is ${bold}d${norm}."

echo -e "${rev}-h${norm} --displays this help message. no further functions are performed."\\n

echo -e "example: ${bold}$script -a foo -b man -c chu -d bar file.ext${norm}"\\n

exit 1

}

#check the number of arguments. if none are passed, print help and exit.

numargs=$#

echo -e \\n"number of arguments: $numargs"

if [ $numargs -eq 0 ]; then

help

fi

### start getopts code ###

#parse command line flags

#如果選項需要後跟參數,在選項後面加":"

#注意"-h"選項後面沒有":",因為他不需要參數。選項字元串最開始的":"是用來去掉來自getopts本身的報錯的,同時擷取不能識别的選項。(譯注:如果選項字元串不以":"開頭,發生錯誤(非法的選項或者缺少參數)時,getopts會向錯誤輸出列印錯誤資訊;如果以":"開頭,則不會列印[在man中叫slient error reporting],同時将出錯的選項賦給optarg變量)

while getopts :a:b:c:d:h flag; do

case $flag in

a) #set option "a"

opt_a=$optarg

echo "-a used: $optarg"

echo "opt_a = $opt_a"

;;

b) #set option "b"

opt_b=$optarg

echo "-b used: $optarg"

echo "opt_b = $opt_b"

c) #set option "c"

opt_c=$optarg

echo "-c used: $optarg"

echo "opt_c = $opt_c"

d) #set option "d"

opt_d=$optarg

echo "-d used: $optarg"

echo "opt_d = $opt_d"

h) #show help

\?) #unrecognized option - show help

echo -e \\n"option -${bold}$optarg${norm} not allowed."

#在這裡如果你不想列印完整的幫助資訊,隻想顯示簡單的錯誤資訊,去掉上面的兩行,同時使用下面的兩行。

#echo -e "use ${bold}$script -h${norm} to see the help documentation."\\n

#exit 2

esac

done

shift $((optind-1)) #this tells getopts to move on to the next argument.

### end getopts code ###

### main loop to process files ###

#這裡你可以用你的腳本處理邏輯來替代。這個例子隻是在終端中列印檔案的檔案名和字尾名。你可以把任意其他的檔案處理任務放到這個while-do循環中。

while [ $# -ne 0 ]; do

file=$1

tempfile=`basename $file`

#tempfile="${file##*/}" #另外一種擷取不帶字尾的檔案名的方法。

file_base=`echo "${tempfile%.*}"` #file without extension

file_ext="${tempfile##*.}" #file extension

echo -e \\n"input file is: $file"

echo "file withouth extension is: $file_base"

echo -e "file extension is: $file_ext"\\n

shift #move on to next input file.

### end main loop ###

exit 0

将上面的代碼複制到你的文本編輯器裡,然後儲存到你的可執行路徑下。我将這個腳本命名為 options 并儲存到 /home/linerd/bin 路徑下。儲存之後記得給你的腳本添加可執行權限。

chmod +x ~/bin/options

現在腳本已經可以運作了。試試用 -h 參數來列印幫助資訊吧。

options -h

遇到不支援的選項,腳本同樣可以給出提示,并列印幫助資訊。

options -z

最後,getopts可以以任意的順序處理你給的指令行參數。唯一的限制是你要處理的檔案必須放在所有參數的最後。

options -d bar -c chu -b man -a foo example1.txt example2.txt

你會用getops來幹什麼呢?在評論裡告訴我吧。

原文釋出時間:2014-06-16

本文來自雲栖合作夥伴“linux中國”

繼續閱讀