Linux LS命令无法正常使用*正则表达式量词[关闭]

问题描述 投票:-2回答:2

如果我有一个目录结构

~/foo/foo1
~/foo/foo2
~/foo/foo3

如果我在〜/ foo中从终端发出以下命令的输出:

  1. ls *foo1*返回0个目录
  2. ls *foo*返回3个目录foo1,foo2和foo3
  3. ls返回3个目录foo1,foo2和foo3
  4. ls -d *foo1*返回foo1
  5. ls | grep *foo1*返回foo1

为什么命令1. ls *Foo1*不返回Foo1?

enter image description here

linux ubuntu
2个回答
0
投票

你真的很困惑,你不太了解任何unix shell的作用。

仔细阅读globbing,特别是glob(7)。它与正则表达式无关(在regex(7)中解释)。 *在shell通配符模式和正则表达式中具有非常不同的角色和含义。 (所以你在标题中提到“正则表达式”是错误的)。

在运行任何程序(甚至像echo之类的任何内置命令)之前,在shell中发生了globbing。仔细阅读documentation of bash,关于shell operation的章节和关于shell expansions的章节。

ls(1)程序(即/bin/ls,因为/bin/在你的PATH variable中)从未在你的情况下看到任何*或任何通配符文件模式。

所以你输入ls *foo*。要了解发生了什么,请在前面键入echo,因此键入命令echo ls *foo*。您将通过shell完成扩展。并且/bin/ls计划正在进行扩展(在execve(2)之后在fork(2)时间内完成了zsh)。

顺便说一句,我更喜欢(交互式使用)bash外壳到auto-completion因为它更好的fish能力(你也可以尝试ls *foo*)。我只需键入zsh后跟tab键,我的*foo*交互式shell立即展开zsh并编辑命令行。如果我对扩展感到满意,那么我只需按下返回键,命令行就会被我的zsh shell解析并执行。如果扩展不是我想要的,ls允许我编辑命令行。

此命令扩展不是特定于stat(1)。 shell启动的任何程序都有通过shell扩展获得的参数列表。在某些情况下,你可能会使用ls(1)而不是aliases(你的shell可能已经定义了ls,所以你的*可能是其他东西的别名)。

由于shell扩展的工作方式,我建议文件名中没有空格或特殊字符(如控制字符和换行符,甚至?quoting)。但是,如果要处理具有奇怪名称的文件路径,则可以使用Parsing Posix [S]hell技术。

另见Yann Regis-Gianas关于crt0的优秀FOSDEM2018谈话

PS。其他OS的工作方式不同。对于Windows(我不知道也从未使用过),有传言说命令扩展发生在程序内部(在某些echo *foo*等价物中)。


1
投票

这与shell文件glob(它与正则表达式不同)无关,它正如预期的那样工作(参见echo *foo1*ls *foo1*)以及ls处理其参数的方式。

  1. 在你的情况下,ls foo1扩展到ls -d *foo1*。这个DOES列出了目录的内容,在你的情况下显然是空的。
  2. 在你的情况下,ls -d foo1扩展到ls *foo*。这列出了foo1目录本身而不是其内容。
  3. http://tldp.org/LDP/abs/html/globbingref.html列出了所有foo *目录的空内容。这导致输出目录名称,即使它们是空的。这些是ls仅在列出多个目录时创建的标头。

进一步阅读:http://man7.org/linux/man-pages/man1/ls.1.html qazxswpoi

© www.soinside.com 2019 - 2024. All rights reserved.