当我按下输入时
(cd <somewhere>/; ls -gG S09E03*
我预计不是与任何文件匹配的目录S09E03*
(我已经验证过),但该命令显示的信息与我想要的文件有关。
所以看起来我的shell(补丁Debian Buster上的zsh,即版本5.7.1)直到它位于正确的目录中(即在.之后cd
)才进行globbing。cd
是一个内置的(它基本上必须是),所以我猜外壳知道我希望它发生在哪里?
我完全没戏了吗?它是否与子外壳有关 -(cd <somewhere1>; ls -l <prefix>*; cd <somewhere2>; ls -l <prefix>*)
显示有关两个不同文件的信息,所以我不这么认为,但我可能(再次)错了?或者是其他什么东西延迟了 globbing(不管我怎么想。
<somewhere>
很长,所以我试图避免在输出中获得该路径ls
ls -gG
因为我知道文件的所有者和组在我想比较某些属性的文件之间会有所不同
Shell(不仅仅是 zsh)在扩展并执行命令之前完成对命令的解析。
;
、&
、|
等),并且对于简单命令,执行参数分配、重定向和从左到右的扩展。请注意,我在这里只给出一个非常笼统的概述。一些极端情况可能很棘手并且依赖于 shell,我不会在这篇文章中讨论这些。
当给定时
(cd subdir/; ls -gG S09E03*)
,shell首先对其进行解析以获得以下结果:cd
,subdir/
(没有带引号的字符)。ls
,-gG
,S09E03*
(没有带引号的字符)。这与 shell 所做的工作相同,例如,如果它正在处理函数定义
一旦它解析了命令,shell就会执行它。它为 subshell 构造创建一个 subshell。在 subshell 内部,它首先展开然后执行第一个简单命令,然后展开然后执行第二个命令。当前目录
subdir/
在执行第一个简单命令期间更改为。的扩展S09E03*
是发生通配步骤的地方,稍后发生。顺便说一句,子外壳只是一个不会改变任何东西的细节。重要的是
;
分开两个命令,第一个命令在第二个命令之前执行。并不是说“shell 知道我想让它发生在哪里”——它正在发生的地方发生。命令参数的扩展总是发生在与命令本身相同的目录中(执行命令的任何部分都不能更改其当前目录,除了可以调用内置函数或在函数内部执行的最后一步)。