我写下了一个使用getopt命令的shell脚本。提供给getopt命令的长选项列表包括以下三个不同的选项:
localaddress
localport
listen
当我用
运行我的脚本时myscript.sh --local xxxx
显然包含一个不明确的选项(--local),getopt将其返回为“--local-address”和零代码。
++ getopt -o a:p: --long localaddress:,localport: -- --local 172.30.2.4
+ AUX='-- --localaddress '\''172.30.2.4'\'
但如果我尝试
myscript.sh --l xxxx
这里getopt确实发现它含糊不清:
getopt: option `--l' is ambiguous
我认为这种行为很奇怪,因为getopt(1)的手册页显示:
Long options may be abbreviated, as long as the abbreviation is not ambiguous.
我错过了什么?
提前完成
P.D:在RHEL5中测试
附录
在我读完 Jonathan Leffler 的答案后,我尝试了一些测试 - 注意结肠模式:
# getopt -V
getopt (enhanced) 1.1.4
# getopt -o a:p: --long localaddress,localport,listen -- --l xxx
--localaddress -- 'xxx'
# getopt -o a:p: --long localaddress,localport,listen: -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
# getopt -o a:p: --long localaddress,localport:,listen -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
# getopt -o a:p: --long localaddress,localport:,listen: -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
# getopt -o a:p: --long localaddress:,localport,listen -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
# getopt -o a:p: --long localaddress:,localport,listen: -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
# getopt -o a:p: --long localaddress:,localport:,listen -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
# getopt -o a:p: --long localaddress:,localport:,listen: -- --l xxx
--localaddress 'xxx' --
2014-05-26更新 - 测试getopt_long(3)
我创建了一个简单的C程序来测试getopt_long(3)函数。
在我的源代码中,传递给getopt_long(3)的结构“option”的数组包含三个长选项“xxaaa”,“xxxyy”和“xxxzz”的定义 - 它们都以相同的字符串开头“xx”测试getopt_long(3)检测模糊选项的能力。
/*
FIELD NAMES OF option STRUCTURE
name has_arg flag val
*/
{ "xxaaa", no_argument, NULL, 9},
{ "xxxyy", no_argument, NULL, 7},
{ "xxxyz", no_argument, NULL, 7},
{ "mmmAA", no_argument, NULL, 3},
{ "mmmBB", required_argument, NULL, 3},
(有关这些字段的详细信息,请参阅getopt_long(3)的手册页。)
注意一个含糊不清的选项,因为“ - XXX”有三个可能的候选者,但“--- xxx”只有两个。
getopt_long的行为根据名为“has_arg”和“val”的两个结构字段的值而变化:
WHEN
the value of "val" field is the same in every possible candidate
AND
the value of the "has_arg" field is the same in every possible candidate,
THEN
the function getopt_long wrongly complains NOTHING about ambiguity
and the first candidate is returned
OTHERWISE
an error message about ambiguity is reported.
从上面的例子中可以看出:
test 1. "--xxx" is WRONGLY admitted as "--xxxyy".
test 2. "--xx" is properly refused as ambiguous.
test 3. "--mmm" is properly refused as ambiguous.
getopt(1)命令在每个“用户定义的长选项”的“val”字段中分配2(在源代码中标记为LONG_OPT)。在启动此线程的情况下,“选项”结构数组将如下所示:
{ "localaddress", required_argument, NULL, 2},
{ "localport", required_argument, NULL, 2},
因此,getopt(1)检测到一个模糊的长选项的唯一方法是候选者在其“has_arg”字段中具有不同的值。
问题
Q1. Why does getopt_long(3) behave that way?
Q2. Why does getopt_long_only(3) not?
Q3. How can the creators of getopt_long(3) be notified? -- I'm not into the linux kernel
development nor I do not use to visit linux kernel websites.
替代方案建议
由于我还不能回答Q1,我认为可以修改getopt(1)命令的源代码,为每个用户定义的long选项在“val”字段中分配不同的值,而不是相同的2(LONG_OPT)值。由于getopt_long(3)在短选项的情况下可以返回单个ASCII字符,这些值应该超出ASCII映射 - val> = 256
答案 0 :(得分:0)
非常好奇!我至少在名义上运行相同版本的getopt
(诚然不在RHEL5上,现在已经很老了,现在,IIRC - 不是那个年龄与它有很大关系),但我不能重现你的结果得到。对于附录中的每个操作示例,我收到警告消息getopt: option `--l' is ambiguous
(并且getopt
的退出状态为1,表示失败)。
for la in '' :
do
for lp in '' :
do
for li in '' :
do
(
set -x
getopt -o a:p: --long localaddress${la},localport${lp},listen${li} -- --l xxx
)
echo $?
done
done
done
+ getopt -o a:p: --long localaddress,localport,listen -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
+ getopt -o a:p: --long localaddress,localport,listen: -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
+ getopt -o a:p: --long localaddress,localport:,listen -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
+ getopt -o a:p: --long localaddress,localport:,listen: -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
+ getopt -o a:p: --long localaddress:,localport,listen -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
+ getopt -o a:p: --long localaddress:,localport,listen: -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
+ getopt -o a:p: --long localaddress:,localport:,listen -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
+ getopt -o a:p: --long localaddress:,localport:,listen: -- --l xxx
getopt: option `--l' is ambiguous
-- 'xxx'
1
这是自洽的,与文档一致。你可以运行显示的脚本并验证输出吗?