[英]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 . 您的选项解析假定在
t
和n
分支中已经设置了$ 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.