简体   繁体   English

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

[英]How to use ${OPTARG} on getopts?

I have the following code: 我有以下代码:

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 is a previously defined function that delivers instructions for a correct call. err-help是先前定义的函数,它为正确的调用提供指令。

A correct call of the script looks like this: ./script.sh -p project_name -t project_type -n source_files_number 正确调用脚本如下所示: ./script.sh -p project_name -t project_type -n source_files_number

What am I trying to do: create a directory with a specific number of source files for ac or a c++ project. 我想做什么:为ac或c ++项目创建一个包含特定数量源文件的目录。

My questions here: How do I have to use the ${OPTARG} ? 我的问题在这里:我如何使用$ {OPTARG}? What exactly does the p=${OPTARG} thing? p = $ {OPTARG}究竟是什么东西? Will the p, t, n variables fill with the right content? p,t,n变量是否会填充正确的内容? How am I doing this right, please? 我该怎么做呢,拜托? :( :(

You are using getopts correctly, but you are making assumptions about what order you're going to see the options. 您正在使用getopts ,但您正在假设您将看到哪些顺序选项。 More on this later. 稍后会详细介绍。

Let's look at a couple of excerpts from help getopts 让我们看几个来自help getopts的摘录

OPTSTRING contains the option letters to be recognized; OPTSTRING包含要识别的选项字母; if a letter is followed by a colon, the option is expected to have an argument , which should be separated from it by white space. 如果一个字母后面跟一个冒号,那么该选项应该有一个参数 ,该参数应该用空格分隔。

... When an option requires an argument, getopts places that argument into the shell variable OPTARG . ...当一个选项需要一个参数时, getopts将该参数放入shell变量OPTARG中

This is the magic of getopts. 这是getopts的神奇之处。 Since you added p: into your optstring, when $0 = "p", the variable $OPTARG will contain whatever you provided to -p , in this case the string "project_name". 由于您在optstring中添加了p: :,当$0 =“p”时,变量$OPTARG将包含您向-p提供的任何内容,在本例中为字符串“project_name”。

Now for some code review: 现在进行一些代码审查:

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

You only need to use braces if you are using arrays, or you need so disambiguate the variable name from the surrounding text ( $o_x vs ${o}_x ) It would be tidier to write 如果使用数组,只需要使用大括号,或者需要从周围文本中消除变量名的歧义( $o_x vs ${o}_x )写起来会更整洁

case "$o" in ...

You don't need to create a special variable with the same name as the option. 您无需创建与选项同名的特殊变量。 You never use $p . 你永远不会使用$p You can just write 你可以写

numep="$OPTARG"

Always quote your variables. 总是引用你的变量。 Always. 总是。 Unless you specifically know when to leave them unquoted. 除非你明确知道何时不加引号。 If I provide -p "some dir with spaces" , then mkdir $numep will create 4 directories. 如果我提供-p "some dir with spaces" ,那么mkdir $numep将创建4个目录。 You need to write 你需要写

mkdir "$numep"

If the $numep directory already exists, you'll get an error message. 如果$ numep目录已经存在,您将收到错误消息。 If you don't want that, use mkdir -p "$numep" (see man mkdir ) 如果你不想那样,请使用mkdir -p "$numep" (参见man mkdir

Now, do address my first concern: there's nothing wrong with invoking your script and providing the options in any order 现在,解决我的第一个问题:调用脚本并以任何顺序提供选项都没有错

./script.sh -t project_type -n source_files_number -p project_name

Your option parsing assumes, in the t and n branches, that you've already set $numep, so you're assuming that the user provided -p first . 您的选项解析假定在tn分支中已经设置了$ numep,因此您假设用户首先提供了-p If -t comes first, then $numep is empty, and you will attempt to create the file /.h . 如果-t首先出现,则$ numep为空,您将尝试创建文件/.h Even if you have permission to write to the root directory, this is not what you want to do. 即使您有权写入根目录,这也不是您想要做的。 Parse all your options before you start doing stuff. 在开始做之前解析所有选项。

I would write this: 我会写这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM