shell记录-传递参数

脚本框架控制参数开始与停止。脚本需要两个参数,如果没有输入两个
参数,那么产生一个u s a g e语句。注意这里使用c a s e语句处理输入脚本的不同参数。

#!/bin/bash
# opt.sh
usage()
{
        echo "usage: `basename $0` start|stop process name"
}      
OPT=$1
PROCESSID=$1
if [ $# -ne 2 ]; then
        usage
        exit 1
fi     
case $OPT in
        start|Start) echo "Starting..$PROCESSID"
        # some process to go here
        ;;
        stop|Stop) echo "Stopping..$PROCESSID"
        # some process to go here
        ;;
        *)usage
        ;;
esac  

执行脚本,输入一下参数,结果为:

[root@localhost ~]# sh opt.sh start named
Starting..start
[root@localhost ~]# sh opt.sh start
usage: opt.sh start|stop process name

任何U N I X或L I N U X命令均接受一般格式:
命令选项文件选项部分最多可包含1 2个不同的值。上述脚本中,如果必须控制不同的命令选项,就要
加入大量脚本。这里只控制两个选项:开始和停止。
幸运的是s h e l l提供s h i f t命令以帮助偏移选项,使用s h i f t可以去除只使用$ 1到$ 9传递参数的
限制。

shift命令
向脚本传递参数时,有时需要将每一个参数偏移以处理选项,这就是s h i f t命令的功能。
它每次将参数位置向左偏移一位,下面用一段简单脚本详述其功能。脚本使用w h i l e循环反馈
所有传递到脚本的参数。

shift命令简单用法
使用s h i f t命令来处理传递到脚本的每一个参数。改动后脚本如下:
#!/bin/bash
# opt2.sh
loop=0
while [ $# -ne 0 ] # while there are still arguments
do
        echo $1
        shift
done
现在执行一下,结果就会明显不同了。如下所示:
file1
file2
file3

命令行输入的最后一个参数
虽然还没有讲e v a l命令,如果需要知道命令行中输入的最后一个参数(通常是一个文件名),
可以有两种选择:使用命令eval echo \$$#;使用s h i f t命令:shift 'expr $# -2'。

------
使用shift处理文件转换
s h i f t可使控制命令行选项更加容易。下面构造一个转换脚本,使用t r将文件名转换为大写
或小写。
脚本选项为:
-l 用于小写转换。
-u 用于大写转换。
使用s h i f t命令将脚本放在一起以控制- l和- u选项。脚本的第一版本如下:

#!/bin/bash
# tr_case.sh
# case conversion
usage()
{
        # usage
        echo "usage: `basename $0` -[l|u] file [files]" >&2
        exit 1
}      
if [ $# -eq 0 ]; then
        # no parameters passed !
fi     
while [ $# -gt 0 ]
do
        case $1 in
                -u|-U) echo "-u option specified"
                # do any setting of variables here for lowercase then shift
                shift
                ;;
                -l|-L) echo "-l option specified"
                # do any setting of variables here for uppercase then shift
                shift
                ;;
                *) usage
                ;;
        esac   
done  

首先检查脚本是否有参数,如果没有,打印u s a g e语句,如果有需要处理的参数,使用
c a s e语句捕获每一个传送过来的选项。当处理完此选项后,使用s h i f t命令搜集命令行中下一选
项,如果未发现匹配选项,打印u s a g e语句。
当向脚本传递两个无效参数时
下一步就是要用c a s e语句处理选项后传递过来的文件名。为此需改动c a s e语句。c a s e语句
中捕获任意模式*应该为- *以允许传递无效选项,例如- p或- q。
*模式也匹配传递过来的所有文件名,以便用f o r循环处理每一个文件,这里也将使用- f选
项检测文件是否存在。
改动后的c a s e语句如下:
case
          ......
                -*) echo "usage: `basename $0` -[l|u] file [file..]"
                exit 1
                ;;
                *) # collect the files to process
                if [ -f $1 ]; then
                        # add the filenames to a variable list
                        FILES=$FILES" "$1
                else   
                        echo "`basename $0`: Error cannot find the file $1"
                fi     
                shift
                ;;
        esac

还需要指定与选项( - l,- u)相关的变量设置。这些变量是:
T R C A S E 保存转换类型(大写或小写)。
E X T 所有文件转换后,大写文件名为. U C,小写为. L C,不保存初始文件状态。
O P T 如果给出此选项,设其为y e s,否则为n o。如果没有给出此选项,捕获此信息并反
馈出来。
其他部分脚本用于实际转换处理,这里即t r命令。t r命令放在c a s e语句f o r循环中读取文件
名进行处理的脚本末尾部分。
以下为完整脚本:
#!/bin/bash
# tr_case.sh
# case conversion
# convert files to either upper or lower case
FILES=""
TRCASE=""
EXT=""
OPT=no
# gets called when a conversion fails
                # do any setting of variables here for lowercase then shift
                shift
                ;;
error_msg()
{
        _FILENAME=$1
               
                shift
                ;;
        echo "`basename $0`: Error the conversion failed on $_FILENAME"
}

if [ $# -eq 0 ]; then
        usage
        # no parameters passed !
fi
while [ $# -gt 0 ]
do
        case $1 in
                # set the variables based on what option was used
                -u) TRCASE=upper
                EXIT".UC"
                OPT=yes
                shift
                ;;
                -l) TRCASE=lower
                EXT=".LC"
                OPT=yes
                shift
                ;;
                -help) echo "convert a file(s) to uppercase from lowercase"
                echo "convert a file(s) from lowercase to uppercase"
                echo "will convert all characters according to the"

                ;;
                echo "  specified command option."
                echo " Where option is"
                echo " -l Convert to lowercase"
                echo " -u Convert to uppercase"
                echo " The original file(s) is not touched. A new file(s)"
                echo "will be created with either a .UC or .LC extension"
                echo "usage: $0 -[l|u] file [file..]"
                exit 0
                ;;
                -*) echo "usage: `basename $0` -[l|u] file [file..]"
                exit 1
                ;;
                *) # collect the files to process
                if [ -f $1 ]; then
                        # add the filenames to a variable list
                        FILES=$FILES" "$1
                else   
                        echo "`basename $0`: Error cannot find the file $1"
                fi     
                shift
                ;;
        esac
done
# no options given ... help the user
if [ "$OPT" == "no" ]; then
        echo " try `basename $0` --help"
        exit 1
fi     
# now read in all the file(s)
# use the variable LOOP, I just love the word LOOP
for LOOP in $FILES
do     
        case $TRCASE in
                lower) cat $LOOP | tr "[a-z]" "[A-Z]" > $LOOP$EXT
                if [ $? != 0 ]; then
                        error_msg $LOOP
                else   
                        echo "Converted file called $LOOP$EXT"
                fi     
                ;;
                upper) cat $LOOP | tr "[A-Z]" "[a-z]" >$LOOP$EXT
                if [ $? !=0 ]; then
                        error_msg $LOOP
                else   
                        echo "Converted file called $LOOP$EXT"
                fi
                ;;
        esac
done  

执行上述脚本,给出不同选项,得结果如下:
转换一个不存在的文件:
[root@localhost ~]# sh tr_case.sh -k cursor
usage: tr_case.sh -[l|u] file [file..]
复制代码
传递不正确选项:
[root@localhost ~]# sh tr_case.sh cursor
tr_case.sh: Error cannot find the file cursor
tr_case.sh : Error you need to specify an option. No action taken
try tr_case.sh --help
复制代码
只键入文件名,希望脚本提示更多帮助信息:
[root@localhost ~]# sh tr_case.sh
For more info try tr_case.sh --help
复制代码
输入两个有效文件及第三个无效文件:
[root@localhost ~]# sh tr_case.sh -l file1 file2 sd
tr_case.sh: Error cannot find the file sd
Converted file called file1.LC
Converted file called file2.LC
复制代码
使用上述脚本可以将许多文件转换为同样的格式。编写一段脚本,使其控制不同的命令
行选项,这种方式编程量很大,是一件令人头疼的事。
假定要写一段脚本,要求控制以下各种不同的命令行选项:
命令-l -c 23 -v 文件1文件2
s h i f t命令显得力不从心,这就需要用到g e t o p t s命令。

猜你喜欢

转载自ancin.iteye.com/blog/1518575