Bash 新手 - 不断收到非法选项错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22909253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
new to Bash - keep getting Illegal option error
提问by Duenna
I'm quite new to ubuntu and bash scripting and wanted to know why I might be getting this error when using GETOPTS.
我对 ubuntu 和 bash 脚本很陌生,想知道为什么在使用 GETOPTS 时可能会出现此错误。
here is the code I use to run it.
这是我用来运行它的代码。
sh /home/ubuntu/Desktop/test.sh -f /home/u/Desktop/ -p 'TEST'
I think i'm calling the script correctly, and it should search for the term I enter as a search term using grap. but for some reason it doesn't. Any advice on what I can do as a general rule when working with grep would also be appreciated, thanks.
我想我正确地调用了脚本,它应该使用 grap 搜索我作为搜索词输入的词。但由于某种原因,它没有。任何关于在使用 grep 时我可以做的一般规则的建议也将不胜感激,谢谢。
#!/bin/bash
valid=0
file_arg=""
display_help=""
column=""
pattern=""
while getopts f:d:s:m: opt
do
case "$opt" in
d) display_help=$OPTARG
;;
f) file_arg=$OPTARG
;;
c) column=$OPTARG
;;
p) pattern=$OPTARG
;;
*) valid=1
break
;;
esac
done
if [ $valid -eq "0" ]
then
if [ $pattern != "" ]
then
cat $file_arg | grep $pattern
else
cat $file
fi
else
echo -n "Usage: FILE -f <name> | COLUMN -> -c <name> | HELP -> -d | PATTERN -> -p <expression>"
fi
回答by Jayesh Bhoi
In getopts
you not specify p
option you only have f:d:s:m:
options.
在getopts
您没有指定p
选项时,您只有f:d:s:m:
选项。
I think you mean p
instead m
or vice versa.
我认为你的意思是p
相反m
,反之亦然。
It should f:d:s:m:p:
or f:d:s:p:
它应该f:d:s:m:p:
或f:d:s:p:
回答by mattst
You should also consider the error supression and error handling features of getopts
.
您还应该考虑getopts
.
If the very first characterof the option string is a colon (:
) then getopts
will not report errors and instead will provide a means of handling the errors yourself. Two additional characters can then be used within your case conditional handling:
如果选项字符串的第一个字符是冒号 ( :
),则getopts
不会报告错误,而是提供一种自己处理错误的方法。然后可以在案例条件处理中使用两个额外的字符:
?
If an invalid option is entered then$opt
will be set to?
and$OPTARG
will hold the invalid character, e.g. if-z
was used, which is not in your option string, then$OPTARG
will be set toz
.:
If a required additional argument is omitted by the user then$opt
will be set to:
and$OPTARG
will hold the command character, e.g. if-p
was used instead of-p arg
then$OPTARG
will be set top
.
?
如果输入了无效选项,$opt
则将设置为?
并$OPTARG
保留无效字符,例如,如果-z
使用了不在您的选项字符串中的字符,$OPTARG
则将设置为z
。:
如果所需的额外的参数是由用户省略然后$opt
将被设置为:
和$OPTARG
将保持命令字符,例如,如果-p
来代替-p arg
然后$OPTARG
将被设置为p
。
If this is implemented then the catch-all of *
becomes redundant and should be removed. Note: If you leave it in and it is above either ?
or :
then you'll be asking for problems. Also make sure the ?
is escaped like this \?)
.
如果实现了这一点,那么包罗万象的内容*
就变得多余了,应该删除。注意:如果你把它留在里面并且它在上面,?
否则:
你会问问题。还要确保?
像这样转义\?)
。
Hope this helps.
希望这可以帮助。
# Note the addition of the inital colon before 'f'.
while getopts :f:d:c:p: opt;
do
case $opt in
d) display_help=$OPTARG
;;
f) file_arg=$OPTARG
;;
c) column=$OPTARG
;;
p) pattern=$OPTARG
;;
# Option error handling.
\?) valid=0
echo "An invalid option has been entered: $OPTARG"
;;
:) valid=0
echo "The additional argument for option $OPTARG was omitted."
;;
# This is now redundant:
# *) valid=0
# break
# ;;
esac
done
回答by Donagh Hatton
There are a couple of other issues with your script, as Jayesh mentioned, you need to include all parameters for getopt but you also need to be careful with string comparisons, here's a couple more fixes with suggestions:
正如 Jayesh 所提到的,您的脚本还有一些其他问题,您需要包含 getopt 的所有参数,但您还需要小心字符串比较,这里有几个修复建议:
(See http://www.tldp.org/LDP/abs/html/comparison-ops.htmlfor string comparison info)
(有关字符串比较信息,请参见http://www.tldp.org/LDP/abs/html/comparison-ops.html)
#!/bin/bash
# switch around valid, convention is 1 == true and 0 == false
valid=1
file_arg=""
display_help=""
column=""
pattern=""
# getopt patterns need to match following case statement
while getopts f:d:c:p: opt;
do
case $opt in
d) display_help=$OPTARG
;;
f) file_arg=$OPTARG
;;
c) column=$OPTARG
;;
p) pattern=$OPTARG
;;
*) valid=0
break
;;
esac
done
# changed value to reflect true false convention
if [ "$valid" -eq "1" ]
then
# string comparison in bash should be done using specific operators
if [ -n "$pattern" ]
then
cat $file_arg | grep $pattern
else
# typo, this should be file_arg?
cat $file_arg
fi
else
echo -n "Usage: FILE -f <name> | COLUMN -> -c <name> | HELP -> -d | PATTERN -> -p <expression>"
fi