如何在getopts上使用$ {OPTARG}?

时间:2016-03-27 12:38:17

标签: linux bash getopts

我有以下代码:

while getopts ":p:t:n:" o; do
case "${o}" in
    p)
        p=${OPTARG}
        numep=$p
        mkdir $numep
        ;;
    t)
        t=${OPTARG}
        tip=$t
        if [ $tip == "c" ]; then
            touch $numep/$numep.c
            touch $numep/$numep.h
        elif [ $tip == "c++" ]; then
            touch $numep/$numep.cpp
            touch $numep/$numep.h
        fi
            ;;
        n)
            n=${OPTARG}
            nrFis=$n
            if [ $tip == "c" ]; then
                for i in $(seq $n); do
                    touch $numep/src/$numep$i.c
                    touch $numep/inc/$numep$i.h
                done
            elif [ $tip == "c++" ]; then
                for i in $(seq $n); do
                    touch $numep/src/$numep$i.cpp
                    touch $numep/inc/$numep$i.h
                done
            fi
            ;;
        *)
            err-help
            ;;
        esac
    done

err-help是一个先前定义的函数,它为正确的调用提供指令。

正确调用脚本如下所示:./script.sh -p project_name -t project_type -n source_files_number

我想做什么:为c或c ++项目创建一个包含特定数量源文件的目录。

我的问题:如何使用$ {OPTARG}? p = $ {OPTARG}究竟是什么东西? p,t,n变量是否会填充正确的内容? 我该怎么做呢,拜托? :(

1 个答案:

答案 0 :(得分:3)

您正在使用getopts,但您正在假设您将查看选项的顺序。稍后会详细介绍。

让我们看一下help getopts

的一些摘录
  

OPTSTRING包含要识别的选项字母; 如果是一封信       后跟一个冒号,该选项应该有一个参数,       白色空间应该与它分开。

     

......当一个选项需要参数时,        getopts将该参数放入shell变量OPTARG

这是getopts的神奇之处。由于您在optstring中添加了p:,因此当$0 =“p”时,变量$OPTARG将包含您向-p提供的任何内容,在本例中为字符串“project_name”

现在进行一些代码审查:

case "${o}" in
    p)
        p=${OPTARG}
        numep=$p
        mkdir $numep
        ;;

如果您正在使用数组,则只需要使用大括号,或者您需要从周围文本($o_x vs ${o}_x中消除变量名称的歧义)写起来会更整洁

case "$o" in ...

您无需创建与选项同名的特殊变量。你永远不会使用$p。你可以写

numep="$OPTARG"

始终引用您的变量。总是。除非你明确知道何时不加引号。如果我提供-p "some dir with spaces",则mkdir $numep将创建 4 目录。你需要写

mkdir "$numep"

如果$ numep目录已经存在,您将收到错误消息。如果您不想这样做,请使用mkdir -p "$numep"(请参阅man mkdir

现在,请解决我的第一个问题:调用脚本并在任何订单中提供选项

没有任何问题
./script.sh -t project_type -n source_files_number -p project_name

您的选项解析假定您已在tn分支中设置了$ numep,因此您假设用户首先提供了-p 。如果-t首先出现,则$ numep为空,您将尝试创建文件/.h。即使您有权写入根目录,这也不是您想要做的。在开始做事之前,先解析所有你的选择。

我会这样写:

while getopts ":p:t:n:" o; do
    case "$o" in
        p)  numep="$OPTARG" ;;
        t)  case "$OPTARG" in
                c)  ext="c" ;;
                "c++")  ext="cpp" ;;
                *)  echo "Error: use 'c' or 'c++' for -t option" >&2
                    exit 1
                    ;;
            esac
            ;;
        n)  nrFis="$OPTARG" ;;
        *)  err-help ;;
    esac
done

mkdir -p "$numep"
touch "$numep/$numep.$ext"
touch "$numep/$numep.h"
for ((i=1; i<=$nrFis; i++)); do
    touch "$numep/src/$numep$i.$ext"
    touch "$numep/inc/$numep$i.h"
done