天天看点

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中国”

继续阅读