命令“sudo mv home/* *”有什么作用?

命令“sudo mv home/* *”有什么作用?

我知道这个命令的每一部分。

sudo mv home/* *
  • sudo:超级用户do,以root权限执行。
  • mv:移动文件或目录。
  • home/*: mv 命令的参数。它表示主目录的内容。星号*是一个通配符,它​​扩展为当前目录中按字典顺序排列的文件列表。

下一个参数是命运文件夹。但是,我指定一个星号作为目标目录,如果执行该命令,该文件夹将完全消失。那么,*在这种情况下是什么?

答案1

home/**是 shell 全局变量,它们首先由 shell 扩展(因此这里以您自己的身份运行,而不是使用超级用户权限),结果是然后作为参数传递给命令。

因此,如果home包含., .., .hidden. u1u2当前目录包含., .., .hidden, -i, x, y,将接收的参数mvmv, home/u1, home/u2, -i, x, y

mv像 GNU 这样的一些实现mv有一个错误特征,即以 开头的参数-仍然被识别为选项,即使它们出现在非选项参数之后,因此上面的内容-i将被视为一个-i选项mvsudo由于明显的原因,没有这个错误特征)。

y将被视为目标目录,如果是目录类型(或目录的符号链接),mv则文件将在其中消失。y

mv不会看到*orhome/*参数(当然,除非确实有这样命名的文件)。但请注意,某些 shell(例如大多数类似 Bourne 的 shell)具有这样的缺陷:如果 glob 与任何文件都不匹配,则会按原样(未扩展)传递给命令。

因此,对于这些,如果当前目录仅包含隐藏文件,则将作为最后一个参数mv接收。不进行特殊处理(shell 的作用是理解 glob),因此会将其视为目标目录的字面名称。现在,如果没有非隐藏文件,该目录也不会存在,因此只会报告有关目标目录不存在的错误。如果只有in ,则会重命名为当前目录。*mv**mv home/u1 home/u2 *u1homemv home/u1 *mvhome/u1*

这个错误特性是由 Bourne shell 于 1979 年引入的。在早期的 Unix 版本中(以及在没有改变它的 csh 中),如果没有一个 glob 匹配,该命令将被取消。然后,glob 被一个/etc/glob助手扩展(glob 的名字由此而来)。如果至少有一个 glob 与任何文件匹配,则不匹配的 glob 将被删除。因此,在 csh/tcsh(或zsh -o cshnullglob)中mv home/* *,当前目录没有非隐藏文件的位置将变为mv home/u1 home/u2将移动u1u2.

现代 shell 像zshor fish(or bash -o failglob) 已经通过在任何 glob 不匹配时取消命令来修复它。

答案2

这完全取决于 shell 通配模式扩展到什么。

它执行以下三件事之一:

  1. 如果*命令末尾的 展开为名称列表,并且该列表中的最后一项是某个名称目录,然后该命令将home/*扩展至的所有内容以及*扩展至的所有内容(但不是最后一个目录名)移动到该目录中。如果扩展为任何内容,并且目标目录尚未包含目录,则匹配的文件和目录将与目标目录中的目录home/*一起找到。homehome/*home

  2. 如果*命令末尾的 展开为名称列表,并且该列表中的最后一项是某个名称不是目录,那么该命令将产生错误。

  3. 如果*根本不展开(因为当前目录为空),则会产生错误。

如果使用mvGNU coreutils 且最后*一个匹配一个或多个以短划线开头的名称,则这可能会更改命令的功能,具体取决于选项mv将名称解释为什么。

答案3

当我自己运行这个程序时,它最终创建了一个*在我的目标文件夹中调用的文件夹,并且还删除了我从中获取的源文件。经过几次测试后,*返回了“不是目录”的预期行为,并且*未创建名为的新目录。

我相信这更符合所提出的问题,因为他表示他的文件消失并echo *返回了*

相关内容