2014-10-17 27 views
6

使用getopt分析命令行参数时,可以在选项标记和所需参数的参数之间插入一个空格,但不能插入可选参数。可选参数只有在选项后面才会被解析。为什么不能使用getopt在选项和可选参数之间有空格?

TEMP=`getopt -o p:q:: -n 'mkqueue.sh' -- "[email protected]"` 

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi 

# Note the quotes around `$TEMP': they are essential! 
eval set -- "$TEMP" 

# Now go through all the options 
while true ; do 
    case "$1" in 
     -p) echo "Option p, argument \`$2'" ; shift 2 ;; 
     -q) 
      case "$2" in 
       "") echo "Option q, no argument"; shift 2 ;; 
       *) echo "Option q, argument \`$2'" ; shift 2 ;; 
      esac ;; 
     --) shift ; break ;; 
     *) echo "Internal error!" ; exit 1 ;; 
    esac 
done 

(在此基础上:http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash

当我运行该脚本没有它的工作原理的可选参数:

./mkqueue.sh -p adfsa -q 
Option p, argument `adfsa' 
Option q, no argument 

如果我尝试添加可选的参数与以-q它之间的空间不起作用:

./mkqueue.sh -p adfsa -q sdfasdfa 
Option p, argument `adfsa' 
Option q, no argument 

它的作品,如果你没有作为尽管所需要的论据适用于空间:

./mkqueue.sh -p adfsa -qsdfasdfa 
Option p, argument `adfsa' 
Option q, argument `sdfasdfa' 

是否有解决方案?

+2

如果它被允许,你会得到另一个问题。假设你的程序也接受一个位置参数。应该将'./a.out -q foo bar'解析为'./a.out -qfoo bar'还是'./a.out -q - foo bar'? – 5gon12eder 2014-10-17 19:11:59

+1

@ 5gon12eder,如果你有这个答案,你至少会得到我的赞赏。它解释了“为什么”,这是这个问题的标题所要求的。 :) – 2014-10-17 19:41:59

回答

8

即限制在联机帮助页记录为getopt

一个简单的短选项是一个' - ”后跟一个短选项字符。如果该选项具有必需的参数,则可以直接在选项字符后面或作为下一个参数(即在命令行上用空格分隔)写入该参数。 如果该选项具有可选参数,则必须在选项字符后面直接写入(如果存在)。

虽然getopt允许“可选的选项参数”,但它们通常被认为是一个坏主意。 POSIX的Utility Syntax Guidelines,例如,包括:

指南7:选项参数不宜选用。

该指南的基本原因是通过约定,命令行选项的参数可以是任何字符串。例如,它可能看起来像另一种选择。它可能是文字字符串--,通常表示选项列表的结尾。它可能是一个空字符串。任何东西。

“可选选项参数”的问题在于,只有知道没有提供可选选项参数的唯一方法是将以下参数识别为选项或--。但这意味着可选参数的值不能以-开头。

或者,您也可以选择由getopt命令行实用程序,这是要求可选参数紧跟选项所采取的解决方案,而无需中间间隔(即在同一个词是)。但是在这种情况下,可选参数不能是空字符串。

与其创建复杂的规则来解决这些歧义问题,简单的解决方案 - 由Posix推荐(并且我的权限更少) - 是不允许选项参数是可选的。如果命令行选项有一个共同的值,并且您希望通过不需要键入命令来简化用户的生活,那么实现两个不同的命令行选项,其中一个选项需要参数,另一个选项没有。常见的技术包括对没有参数的版本使用小写字符,对于带有参数的版本使用相应的大写字符,或对该版本使用长选项(--option)。

对于那些谁喜欢密集和包装的说明中,POSIX rationale解释说:

指南7允许任何字符串是一个选项参数;选项参数可以以任何字符开头,可以是---,并且可以是空字符串。例如,命令pr -h -pr -h --pr -h -dpr -h +2,和pr -h '',分别----d+2,和一个空字符串包含选项参数。相反,命令pr -h -- -d将-d作为选项,而不是作为参数,因为--是此处的选项参数,而非分隔符。

+0

这是一个很好的解释,并完成,但我觉得有点密集。打开基本原理的例子可能会有所帮助(不是每个人都知道' - '的意思,f'rinstance)。 – 2014-10-17 20:10:29

相关问题