- 指定时应
ls --directory a*
仅列出以以下内容开头的目录a*
- 但它列出了以以下开头的文件和目录
a
问题:
man
除了我认为我彻底查看过的地方之外,我可以在哪里找到有关此问题的一些文档info
?- 这仅适用于 BASH 吗?
答案1
a*
and语法*a*
是由 shell 实现的,而不是由ls
命令实现的。
当您输入时
ls a*
在 shell 提示符下,shell 会展开a*
为当前目录中名称以a
.例如,它可能扩展a*
到序列a1 a2 a3
,并将它们作为参数传递给ls
。命令ls
本身永远看不到*
角色;它只看到三个参数a1
、a2
和a3
。
出于通配符扩展的目的,“文件”指当前目录中的所有实体。例如,a1
可能是普通文件,a2
可能是目录,也a3
可能是符号链接。它们都有目录条目,并且 shell 的通配符扩展并不关心这些条目引用的实体类型。
实际上,您可能遇到的所有 shell(bash、sh、ksh、zsh、csh、tcsh...)都实现了通配符。细节可能有所不同,但*
匹配零个或多个字符以及?
匹配任何单个字符的基本语法相当一致。
特别是对于 bash,这在 bash 手册的“文件名扩展”部分中有记录;运行info bash
并搜索“文件名扩展”,或者查看这里。
事实上,这是由 shell 而不是单个命令完成的,这会产生一些有趣(有时令人惊讶)的后果。最好的一点是,通配符处理对于(几乎)全部命令;如果 shell 不这样做,不可避免地有些命令不会打扰,而其他命令会以作者认为“更好”的微妙不同的方式来完成。 (我认为Windows命令shell有这个问题,但我对它还不够熟悉,无法进一步评论。)
另一方面,编写一个命令来重命名多个文件是很困难的。如果你写:
mv *.log *.log.bak
它可能会失败,因为它*.log.bak
是根据当前目录中已存在的文件进行扩展的。有一些命令可以执行此类操作,但它们必须使用自己的语法来指定如何重命名文件。某些命令(例如find
)可以进行自己的通配符扩展;你必须引用参数来抑制 shell 的扩展:
find . -name '*.txt' -print
shell 的通配符扩展完全基于命令行参数的语法和现有文件集。它不能受命令含义的影响。例如,如果要将所有.log
文件移至父目录,可以键入:
mv *.log ..
如果您忘记了..
:
mv *.log
.log
并且当前目录中恰好有两个文件,它将扩展为:
mv one.log two.log
这将重命名one.log
并破坏two.log
.
编辑:在 52 票赞成、1 票接受和一枚大师徽章之后,也许我实际上应该回答标题中的问题。
-d
或选项--directory
并不ls
告诉它仅列出目录。它告诉它像目录一样列出目录,而不是目录的内容。如果您将目录名称作为参数提供ls
,默认情况下它将列出内容目录的名称,因为这通常是您感兴趣的内容。该-d
选项告诉它仅列出目录本身。当与通配符结合使用时,这会特别有用。如果您输入:
ls -l a*
ls
将为您提供每个的长列表文件名字以a
, 开头的内容每个以 开头的目录a
。如果您只想要文件和目录的列表(每个文件和目录占一行),则可以使用:
ls -ld a*
这相当于:
ls -l -d a*
再次记住,该ls
命令永远不会看到该*
字符。
至于记录在哪里,将向您展示几乎任何类 Unix 系统上man ls
该命令的文档。ls
在大多数基于 Linux 的系统上,该ls
命令是 GNU coreutils 软件包的一部分;如果您有info
命令,或者info ls
或info coreutils ls
应该为您提供更明确和全面的文档。其他系统,例如MacOS,可能使用不同版本的命令ls
,也可能没有该info
命令;对于这些系统,请使用man ls
.并ls --help
会显示一个相对地简短的使用消息(我的系统上有 117 行)如果您正在使用 GNU coreutils 实现。
是的,即使是专家也需要时不时地查阅文档。也可以看看这个经典笑话。
答案2
参见基思·汤普森的回答;但要解释为什么ls --directory a*
显示文件和目录:该--directory
选项不抑制非目录文件。相反,它会按原样列出目录,而否则会列出其内容。例子:
$ mkdir foo
$ touch foo/bar
$ ls foo
bar
$ ls --directory foo
foo
答案3
非常明确地说,它记录在ls(1) 手册页:
-d, --目录 列出目录条目而不是内容,并且不取消引用符号链接
公平地说,“条目而不是内容”可能更具解释性:
如果 FILE 是目录,则显示目录条目本身,而不是列出该目录的内容。如果 FILE 是符号链接,则显示链接条目本身,而不是链接指向的文件。
答案4
文档没有说它列出了仅有的目录条目 bur 相反,当ls
收到目录名称时,它会列出目录条目代替这是内容。最好的理解方法是通过示例:
> {ice} ~ :10:47 % ls -l /
total 97
drwxr-xr-x 2 root root 4096 May 3 00:27 bin
drwxr-xr-x 4 root root 1024 May 3 14:17 boot
drwxr-xr-x 2 root root 4096 Apr 29 13:44 cdrom
drwxr-xr-x 18 root root 4420 May 9 09:58 dev
...
lrwxrwxrwx 1 root root 33 May 3 14:16 vmlinuz -> boot/vmlinuz-3.9.0-030900-generic
lrwxrwxrwx 1 root root 29 May 3 11:07 vmlinuz.old -> boot/vmlinuz-3.8.0-19-generic
> {ice} ~ :10:47 % ls -ld /
drwxr-xr-x 25 root root 4096 May 3 14:16 /