为什么ls接受重复的开关?


16

我很好奇- ls -l和之间有区别ls -lllllllllllllllllllllllllllll吗?

输出似乎是相同的,我对为什么ls允许重复开关感到困惑。这是大多数命令中的标准做法吗?

Answers:


17

简短答案

因为它被编程为忽略标志的多次使用。

长答案:

如您在的源代码中所看到的ls,该函数的一部分getopt_long()和一个很大的开关盒:

1648       int c = getopt_long (argc, argv,
1649                            "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
1650                            long_options, &oi);
      ....
1654       switch (c)
1655         {
      ....
1707         case 'l':
1708           format = long_format;
1709           break;
      ....
1964     }

该函数getopt_long()读取提供给程序的所有参数。如果设置-l了变量format。因此,当您键入多个时-lllllllll,该变量会被设置多次,但这不会改变任何内容。

好吧,它改变了一件事。由于存在多个-l标志,因此巨大的switch case语句必须运行多次。ls需要更长的时间才能完成多个-l标志。但这一次不值一提。=)


11
换句话说,对于程序员来说,拒绝它们比忽略它们会是更多的工作。
2014年

1
+0.5表示我要说的内容,+ 0.5表示来源。
2014年

21

因为这是正确的事情。假设您有一个脚本在执行以下操作:

ls $LS_OPTIONS -l "$dir"

在可能$LS_OPTIONS已经包含的地方-l。该命令产生错误将是违反直觉的并且令人讨厌,并且将需要脚本中的额外逻辑来避免该错误。

-l也许不是最好的例子,但希望您能看到该概念在总体上的应用。一个更好的例子是编译器选项,$CFLAGS它可能在特定的编译器调用中复制显式选项。


4
如果您定义了一个别名,ls并使用一组选项进行调用,也会发生同样的事情。
kasperd 2014年

1
@kasperd:是的。尽管-l输入ls别名似乎不是一个好主意,但是在交互式ls别名(例如-p或)中使用不错的选项也可能会出现相同的问题--color=auto
R .. GitHub停止帮助ICE

1
别名不必被调用lsll可能是的别名ls -l,在具有该别名的系统上,我可以输入ll -lart
kasperd 2014年

11

ls不是bash命令,而是您恰巧从中启动的单独可执行文件bash。也就是说,这-l只是布尔型标记的一种,如果存在,它会导致ls对输出使用长样式格式。尽管有一些例外情况(例如,如果表示“冗长”,则程序可能将多种用途解释为“甚至更冗长”),大多数程序将简单地忽略此类标志的多种用法(ls -ll与相同)。ls -l -l-v


2
的一个示例-vvvssh
2014年

甚至aptitude moo
Ruslan 2014年

8

如果类似ls这样的命令不允许重复的选项,则Shell别名会很烦人。

假设你有

alias ls='ls --color=auto'
alias rm='rm -i'

然后,如果不允许冲突的标志,则发出诸如ls --color=neverls --color=auto或命令之类的错误rm -i

因此,这些命令旨在让后面的标志覆盖前面的标志。


有时不允许发生冲突的开关。(例如,尝试同时使用--inplace和和rsync --delay-updates。)一些工具会采取最后的行动;rm -if那里可能是一个很好的例子。但在LS的-l选项没有冲突,因此ls -lls -ll不是一个问题,它不以任何方式显著影响执行。计算机擅长于使人麻木的重复。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.