如果您输入命令ls *
和echo *
,您会发现结果之间存在显着差异。前者递归包含,后者完全排除子目录中的文件。它们对于路径名扩展的行为不一样吗?
答案1
ls
如果作为参数传递,则默认列出目录的内容。当你传递*
到你的 shell 时,你的外壳扩展*
到所有文件和目录(在当前工作目录中),然后ls
获取这些参数并处理它们。结果,它列出了指定目录的内容以及当前工作目录中的文件。
在 的情况下echo
,shell 扩展了 ,*
并且您无法获取目录内容,因为 echo 只打印作为参数传递给它的内容。
您可以ls
使用 来告诉不要显示目录的内容ls -d *
。
鉴于此设置:
$ mkdir dir{1,2}
$ touch file{1..3} dir{1,2}/morefiles{1..5}
$ ls
dir1 dir2 file1 file2 file3
传递*
到 shell (bash),导致 bash 扩展*
为dir1 dir2 file1 file2 file3
.使用echo
with *
, 将echo
显示 shell 的扩展内容*
:
$ echo *
dir1 dir2 file1 file2 file3
但是,默认情况下,给定的目录参数ls
将扩展列出的目录的内容:
$ ls *
file1 file2 file3
dir1:
morefiles1 morefiles2 morefiles3 morefiles4 morefiles5
dir2:
morefiles1 morefiles2 morefiles3 morefiles4 morefiles5
$
您可以删除*
on ls
(如我创建示例目录结构后所示),或者如我的答案中提到的那样使用ls -d *
:
$ ls -d *
dir1 dir2 file1 file2 file3
这将停止显示和ls
的内容。dir1/
dir2/
答案2
只是为了澄清 DravSloan 的出色答案,没有任何差异。*
在这两种情况下都由 shell 扩展,并且在这两种情况下它都扩展为完全相同的东西。区别在于他们的论点的方式echo
和ls
对待方式。
echo
只会打印您提供的每个参数。ls
将要list directory contents
正如手册所说。因此,在这两种情况下,shell 都会执行左侧的程序(echo
或ls
),并且相关程序会对其每个参数执行其应执行的操作。结果不同是因为程序不同,而不是因为*
扩展不同。