shell 中的路径名扩展后返回什么?

what is returned after pathname expansion in shell?

1、以白色分隔的字符串space?
如果我在有很多TXT文件的地方执行rm -r *.txt,我得到一个"Argument list too long"错误,它似乎告诉我它在路径名扩展后等于rm -r a.txt b.txt...c.txt
2、只是特定命令使用的列表对象?
如果我在有两个TXT文件("a.txt"和"b.txt")的地方执行tar --exclude *.txt a.tar.gz a,结果与执行tar --exclude a.txt b.txt a.tar.gz a不一样。据此,也许我们可以得到结论是只返回一个列表对象,而不是用白色 space.

分隔的字符串

我有一个名为a的目录,结构如下: a ├── a.txt ├── b.txt └── cc

如果我执行tar --exclude *.txt -czvf a.tar.gz a,我得到的结果是: a/ a/cc

"a.tar.gz"没有*.txt文件生成成功。 如果我执行 tar --exclude a.txt b.txt -czvf b.tar.gz a,我得到的结果是: tar: b.txt:cat not stat: no such file or directory a/ a/cc a/b.txt

"b.tar.gz" 是在没有 a.txt 和有 cc 和 b.txt

的情况下生成的

@Jan Hudec

以白色分隔的字符串space。在将参数传递给命令之前,扩展由 shell 完成。使用 tar 时,如果要将模式传递给 --exclude 选项,请将其放在单引号之间,例如 tar --exclude '*.txt' -czf a.tar.gz a

都没有。它 returns 一个 字符串列表 .

生成文件名之前执行分词,因此在这一点上,shell已经使用将构成命令的字符串列表。生成的文件名作为一个单独的条目插入到该列表中。

If I execute rm -r *.txt where there is a lot of TXT file,I get an "Argument list too long" error,it seems to tell me that it equasl to rm -r a.txt b.txt...c.txt after pathname expansion.

所以,是的,是的。如果某些文件的名称中包含 space,它将被正确传递(如果模式返回 space 分隔的字符串则不会)。然而:

If I execute tar --exclude *.txt a.tar.gz a where there are two TXT files ("a.txt" and "b.txt") ,the result is not the same as executing tar --exclude a.txt b.txt a.tar.gz a.

您忘记提及这些文件位于 a 目录中。因此 *.txt 而不是 扩展为 a.txtb.txt,因为没有这样的文件——只有 a/a.txta/b.txt。这里出现了 quick of bash(zsh 可以任意配置):不匹配任何内容的模式将保持原样。所以

tar --exclude *.txt a.tar.gz a

扩展为 tar--exclude*.txta.tar.gzatar--exclude 选项的参数进行自己的通配符处理。

但是,如果当前目录中还有 c.txtd.txt,它将扩展为 tar--excludec.txtd.txta.tar.gza 并分解。为防止这种情况,请引用模式:

 tar --exclude '*.txt' a.tar.gz a