不同用户对文件或目录进行 cp、mv 和重命名或建立硬/符号链接需要什么权限?

Cru*_*se5 1 linux permissions

root我可以使用以下权限将 /etc/passwd 文件复制到我的主目录:

-rw-r--r--. 1 root root 2751 Dec 24 21:26 /etc/passwd
Run Code Online (Sandbox Code Playgroud)

我不能做同样的事情:

-rw-------. 1 root root 43591 Dec 27 18:32 /var/log/messages
Run Code Online (Sandbox Code Playgroud)

所以我猜测 的读取权限使得others复制成为可能?

为了创建硬链接,我在主目录中以 root 用户身份创建了 file1,并尝试以普通用户身份创建硬链接。我没能做到。

-rw-r--r--. 1 root root 0 Dec 27 18:39 file1

是什么阻止了硬链接的创建?

file1所在目录权限为: drwx------. 18 student student 4096 Dec 27 18:42 .

我能够将 file1 重命名为 file2 所以我猜测,与复制相同,读取权限正在others使这种情况发生?

最后,我无法将 file2 移动到其他位置。为什么?

编辑:我看过一个解释硬链接权限的问题,但我不明白复制、移动和重命名其他用户的文件和目录需要什么权限。

Jör*_*tag 12

基本隐喻:目录不是文件夹

\n

要理解的基本概念是目录的概念。这很重要:Unix 没有文件它有目录

\n

这种区别很重要:文件夹包含内容。目录列出了事物。如果您想到文件夹,您的脑海中就会出现错误的比喻。想象一下您在办公楼大厅中找到的公司目录:该目录不包含办公室,而是列出了它们。同样,你的电话簿不包含你的朋友,它列出了他们。另一方面,(物理)文件夹实际上包含它所保存的(物理)文件。

\n

文件序列号

\n

在 Unix 中,文件没有名称。文件只有一个文件序列号 (FSN)。FSN 在单个文件系统中是唯一的:同一文件系统上没有两个文件具有相同的 FSN,并且单个文件在其生命周期内仅具有单个 FSN。但请注意,不同文件系统上的文件可以具有相同的 FSN。

\n

索引节点

\n

注意:您可能会遇到术语inode。它本质上意味着同样的事情。文件序列号是为 Unix 标准化而发明的名称,因为索引节点实际上是某些文件系统的实现细节,许多现代文件系统甚至不再索引节点 \xe2\x80\xa6 但它们仍然需要有 FSN 。此外,许多现代的 Unices 允许挂载外部文件系统,这些文件系统显然也没有 inode,因为这纯粹是 Unix 的事情(例如,在 Linux 中挂载 FAT、exFAT 或 NTFS 文件系统)。不过,这些外部文件系统的 Unix 驱动程序仍然需要合成 FSN,因为许多文件系统 API 都是基于 FSN 的。

\n

目录

\n

目录是将名称FSN相关联的特殊文件。在非常早期、非常简单的 Unix 文件系统中,目录实际上只是一个文件(类似于文本文件),看起来像

\n
12345 foo\n54321 hello.txt\n34343 My 2021 taxes.xlsx\n
Run Code Online (Sandbox Code Playgroud)\n

当然,现代文件系统要复杂得多,但从概念上讲,即使在最复杂的文件系统中,这仍然是当今的工作方式。

\n

三个基本概念

\n

如果您了解这三个概念,您就了解了有关 Unix 文件系统和 Unix 权限所需了解的一切:

\n
    \n
  • 文件没有名称,只有文件序列号。
  • \n
  • 目录是文件。
  • \n
  • 目录将名称与 FSN 相关联。
  • \n
\n

想想我们的电话系统是如何工作的:我们只有号码,但我们有目录(电话簿、黄页,或者在更现代的情况下,我们手机上的联系人应用程序)将姓名与这些号码相关联。

\n

(硬)链接

\n

名称FSN之间的关联称为链接,有时称为硬链接(在可能与符号链接/软链接混淆的上下文中)。

\n

三个基本概念的后果

\n

一旦你内化了这三个概念,其他一切都应该水到渠成。

\n

现在应该很明显,没有什么可以阻止您在不同目录甚至同一目录中为同一 FSN 创建多个 name\xe2\x86\x92FSN 链接。换句话说,同一个文件可以有多个名称并存在于多个路径中。

\n

很明显,这会导致分层目录结构:因为目录只是像任何其他文件一样的文件,所以它们像任何其他文件一样具有 FSN,因此,我可以在目录中列出目录。

\n

不太明显但重要的是要了解该rm实用程序实际上并不删除文件!它删除一个链接,换句话说,它删除目录中的一个条目。所使用的库函数和内核系统调用rm实际上是被调用的unlink。事实上,您实际上无法在 Unix 中删除文件。如果没有指向文件的链接(换句话说,如果文件有 0 个名称)并且文件没有打开的文件句柄,文件将被自动删除。

\n

这也解释了许多 Windows 用户感到困惑的事情:我怎么可能删除在某些应用程序中仍然打开的文件?该应用程序如何不崩溃?好吧,根据我们在上一段中学到的知识,答案很简单:他们没有删除文件,他们只删除了名称。该文件仍然存在。它仍然可以有其他名称,但即使这是最后一个名称,该文件也不会被删除,直到应用程序关闭它。事实上,创建一个临时文件,打开它,然后立即再次“删除”它,是需要临时存储数据但又不想用临时文件弄乱文件系统的 Unix 应用程序的常见设计模式。

\n

将概念应用于权限

\n

如果您了解目录是文件,并且目录将名称与数字相关联,那么权限就会变得清晰:

\n
    \n
  • 如果要重命名,则需要将新名称写入目录并删除(这也是写入的一种形式)旧名称,因此您需要对该目录w具有rite 权限,但无法访问该文件。事实上,重命名实际上与文件本身没有任何关系,它只涉及名称不是文件本身的属性。
  • \n
  • 如果要列出目录,则需要读取其内容,因此需要r对该目录的读取权限。
  • \n
  • 创建硬链接只是写入目录,因此您需要w对该目录的写入权限。等等。
  • \n
\n

具体例子

\n

考虑到我们的三个核心概念,我们应该能够回答您的所有问题:

\n

复制

\n
\n

我可以使用以下权限将/etc/passwd拥有的文件复制到我的主目录:root

\n
-rw-r--r--. 1 root root 2751 Dec 24 21:26 /etc/passwd\n
Run Code Online (Sandbox Code Playgroud)\n

我不能做同样的事情:

\n
-rw-------. 1 root root 43591 Dec 27 18:32 /var/log/messages\n
Run Code Online (Sandbox Code Playgroud)\n

所以我猜测 的读取权限使得others复制成为可能?

\n
\n

那是对的。想想“复制文件”的实际含义是什么:您正在创建一个文件(这自动意味着您需要给它一个名称,即在目标目录中创建一个链接条目),该文件与原始文件具有相同的内容文件。

\n

为此,您需要两个权限:

\n
    \n
  • 您需要w目标目录的 rite 权限才能创建指向新创建文件的硬链接。
  • \n
  • 您需要r原始文件的 ead 权限才能读取其内容,因为如果您无法读取其内容,那么如何重新创建它?
  • \n
\n

关联

\n
\n

为了创建硬链接,我file1在主目录中创建了 root 用户,并尝试以普通用户身份创建硬链接。我没能做到。

\n
-rw-r--r--. 1 root    root       0 Dec 27 18:39 file1\n
Run Code Online (Sandbox Code Playgroud)\n
\n

标准 Unix 权限模型中没有任何内容可以阻止您创建硬链接。您所需要的只是w对该目录的 rite 权限。该文件的权限是无关紧要的,因为您不需要触及它。

\n

我刚刚在我的操作系统(macOS 12.1“Monterey”)的 APFS 文件系统上测试了它,它运行得很好。

\n

fs.protected_hardlinks

\n
\n

是什么阻止了硬链接的创建?

\n
\n

Unix 权限系统中没有任何内容。但是,由于您使用的是 Linux,因此有一个特定于 Linux 的配​​置选项可能会阻止您这样做:sysctl fs.protected_hardlinks

\n

引用官方 sysctl 文档[粗体强调我的]:

\n
\n

受保护的硬链接

\n

[\xe2\x80\xa6]

\n

当设置为“0 ”时,硬链接创建行为不受限制。

\n

当设置为“ 1时,如果用户尚不拥有源文件,或者没有对该源文件的读/写访问权限,则无法创建硬链接

\n
\n

看起来您已将其配置为1(受限)。检查/proc/sys/fs/protected_hardlinks确定。

\n

改名

\n
\n

file1所在目录权限为:

\n
 drwx------. 18 student student 4096 Dec 27 18:42 .\n
Run Code Online (Sandbox Code Playgroud)\n

我能够将其重命名file1为,file2所以我猜测,与复制相同,读取权限others正在使这种情况发生?

\n
\n

对于重命名,您只需要w对您拥有的目录具有 rite 权限。您永远不会触及该文件的内容,因此其权限无关紧要。

\n

移动

\n
\n

最后,我无法搬到file2其他地方。为什么?

\n
\n

这取决于您所说的“移动”到底是什么意思,您所说的“不同位置”到底是什么意思,以及您所说的“不能”到底是什么意思。

\n

有两种方式可以解释“移动”:

\n
    \n
  1. 删除原始内容并以不同的名称重新创建相同的内容。
  2. \n
  3. 删除源目录中的链接并在目标目录中创建链接。
  4. \n
\n

如果您使用该mv实用程序,它实际上可以执行其中任何一个操作,所以让我们看看它们。

\n

#2 只是重命名:您需要w对源目录具有 rite 权限,以便可以删除链接,并且需要w对目标目录具有 rite 权限,以便可以创建链接。您在任何时候都不需要接触该文件或访问其内容,因此权限无关紧要。事实上,将为此mv使用系统调用。rename

\n

mv只要有可能,就会尝试做#2。

\n

那么,什么时候#2 是不可能的呢?好吧,请记住,FSN 仅在一个文件系统中是唯一的。此外,文件仅存在于文件系统中

\n

因此,应该清楚的是,只有当源目录和目标目录位于同一文件系统上时,#2 才是可能的。如果它们位于不同的文件系统上,mv则会将文件复制到目标,然后取消链接原始文件。这意味着,正如我们上面讨论的,除了对w源目录的 rite 访问和w对目标目录的 rite 访问之外,还需要r对原始文件进行 ead 访问。

\n

执行权限

\n

注意:到目前为止,我们只查看了read 和write 权限,但我们完全忽略了 ex ecute 权限。

\n

\xe2\x80\xa6 用于常规文件

\n

对于常规文件,e xecute 权限相当明显:它授予执行该文件的权限。(不,真的吗?)但是,请注意“执行”在这里有特定的含义:它的意思是“将其传递给内核来执行”。

\n

特别是,您不需要执行x权限即可将文件传递给脚本解释器。因此,如果您有一个以名为 MyLanguage 的虚构语言调用的脚本文件,myscript如下所示:

\n
#!/usr/bin/env mylanguage\n\nprint "Hello, World!"\n
Run Code Online (Sandbox Code Playgroud)\n

那么如果你像这样执行它,你确实需要 e ecute 权限:x

\n
/path/to/myscript\n
Run Code Online (Sandbox Code Playgroud)\n

但如果您像这样执行它,则不需要 e ecute权限x

\n
mylanguage /path/to/myscript\n
Run Code Online (Sandbox Code Playgroud)\n

语言解释器只需要r读权限,就可以读取脚本文件的内容。

\n

或者,更准确地说,系统不要求您具有 e xecute 权限,但mylanguage解释器可以根据需要检查您是否具有 e xecute 权限。事实上,有些口译员会这样做,有些则不会。

\n

\xe2\x80\xa6 用于目录

\n

xe ecute 权限对于目录意味着什么?这里正在执行什么?

\n

对于目录,e xecute 权限被解释为“输入”权限或“查找”权限。换句话说,e xecute 权限允许您向目录请求 FSN(给定名称)。

\n

您可以将目录视为一个非常简单的程序,它以名称作为参数并返回FSN,那么“e ecute 权限”的想法x就有意义了。但这确实是一个非常费力的想法。x只需忽略e ecute 的代表这一事实x,并考虑x目录的“查找”或“输入”含义。

\n

其他类型的特殊文件

\n

目录并不是唯一的特殊文件类型。还有其他五个:

\n
    \n
  • 符号链接,
  • \n
  • 管道,
  • \n
  • 插座,
  • \n
  • 字符特殊文件,以及
  • \n
  • 阻止特殊文件
  • \n
\n

符号链接

\n

在这五个中,您最常遇到的是符号链接符号链接

\n

符号链接本质上是一个包含路径的文件。在非常早期、非常简单的 Unix 文件系统中,符号链接实际上只是包含路径的文本文件。今天你或多或少仍然会这样看待它们。

\n

一旦理解了这一点,就应该清楚,为了创建到某个地方的符号链接,您需要做的就是创建文件。您不需要访问放入文件中的路径。事实上,这条路甚至不必存在!

\n

例如,假设您被允许创建文件,您可以轻松地执行

\n
ln -s https://www.google.com/ google\n
Run Code Online (Sandbox Code Playgroud)\n

这是一个完全有效的符号链接:google是一个完全有效的名称,https://www.google.com/也是一个完全有效的路径(它的意思是“www.google.com在当前目录中指定的目录https:中指定的目录),但它当然不是指向实际存在的文件,尽管您可以

\n
mkdir -p https:/www.google.com\n
Run Code Online (Sandbox Code Playgroud)\n

如果您愿意,可以让它指向某个地方:

\n
cd google\n# no error\n
Run Code Online (Sandbox Code Playgroud)\n