【问题标题】:How to use ${OPTARG} on getopts?如何在 getopts 上使用 ${OPTARG}?
【发布时间】:2016-07-14 19:57:09
【问题描述】:

我有以下代码:

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 变量会填充正确的内容吗? 请问我怎么做对了? :(

【问题讨论】:

  • Thereexistmanytutorialsaboutgetopts。你到底有什么问题?
  • 就像我说的。我分析了很多教程,这就是我以后可以写的。如果我为每个案例写 p=${OPTARG},t=${OPTARG},n=${OPTARG}。这些变量是否包含正确的数据?还是所有内容都相同?我不知道这里的诀窍......
  • 是的,它们将包含正确的数据。

标签: linux bash getopts


【解决方案1】:

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

让我们看一下help getopts的一些摘录

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

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

这就是 getopts 的魔力。由于您将p: 添加到您的optstring 中,当$o = "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,因此您假设用户提供了-pfirst。如果 -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

【讨论】:

  • 是的,您对 -p -t -n 的顺序是正确的。我稍后会通过 throw 你的代码并返回我的问题或结果。谢谢你的时间,格伦! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 2013-05-05
相关资源
最近更新 更多