Cp命令

来自泡泡学习笔记
跳到导航 跳到搜索

cp:复制文件和目录

cp用于复制文件(或者可选地复制目录)。复制是与原文件完全独立的。您可以将一个文件复制到另一个文件,或者将任意数量的文件复制到目标目录。语法如下:

cp [选项]… [-T] 源文件 目标文件
cp [选项]… 源文件… 目标目录
cp [选项]… -t 目标目录 源文件…

如果指定了两个文件名,cp将第一个文件复制到第二个文件。

如果给出了--target-directory (-t)选项,或者最后一个文件是目录且没有给出--no-target-directory (-T)选项,则cp将每个源文件复制到指定的目录中,使用源文件的名称。

通常,文件以其读取的方式进行写入。有关例外情况,请参见下面的--sparse选项。


默认情况下,cp不会复制目录。然而,-R、-a和-r选项会使cp递归地进入源目录并将文件复制到相应的目标目录中。


当从符号链接复制时,cp通常只在不递归复制或使用--link (-l)选项时才会遵循该链接。可以使用--archive (-a)、-d、--dereference (-L)、--no-dereference (-P)和-H选项来覆盖此默认行为。如果指定了多个这些选项中的一个,最后一个选项会静默地覆盖其他选项。


当复制到一个符号链接时,只有当该链接指向一个现有的普通文件时,cp才会遵循该链接。然而,当复制到一个悬空的符号链接时,默认情况下cp会拒绝复制,并显示诊断信息,因为这个操作本质上是危险的。这种行为与历史惯例和POSIX标准相违背。设置POSIXLY_CORRECT变量可以使cp尝试创建一个悬空目标符号链接的目标,尽管可能存在风险。此外,当像--backup或--link这样的选项在复制之前重命名或删除目标时,cp会重命名或删除符号链接而不是它指向的文件。


默认情况下,只有在不递归复制时,cp才会复制特殊文件的内容。可以使用--copy-contents选项来覆盖此默认行为。


通常情况下,cp拒绝将文件复制到自身,但有一个例外情况:如果使用--force --backup选项并且源文件和目标文件相同,并且引用的是一个普通文件,cp将创建一个备份文件,可以是普通备份文件或者带编号的备份文件,具体方式可以参考常规方式(请参阅备份选项)。这在您只是想在修改文件之前备份现有文件时非常有用。


该程序接受以下选项。另请参阅常见选项。


‘-a’

‘--archive’

尽量保留复制文件中原始文件的结构和属性(但不尝试保留内部目录结构;即‘ls -U’可能会以不同的顺序列出复制目录中的条目)。尽量保留SELinux安全上下文和扩展属性(xattr),但忽略任何无法保留的失败并不打印相应的诊断信息。相当于 -dR --preserve=all,但诊断信息更少。


‘--attributes-only’

仅将源文件的指定属性复制到目标文件。如果目标文件已存在,则不更改其内容。有关控制要复制的属性的详细信息,请参阅 --preserve 选项。


‘-b’

‘--backup[=method]’

请参阅备份选项。对每个将被覆盖或删除的文件进行备份。作为特例,当给出 force 和 backup 选项并且源文件和目标文件是同名的现有常规文件时,cp 会备份源文件。这种组合选项的一个有用应用是这个小型的 Bourne shell 脚本:

#!/bin/sh
# Usage: backup FILE...
# Create a GNU-style backup of each listed FILE.
fail=0
for i; do
  cp --backup --force --preserve=all -- "$i" "$i" || fail=1
done
exit $fail


‘--copy-contents’

如果进行递归复制,则将任何特殊文件(例如,FIFO 和设备文件)的内容复制为普通文件。这意味着尝试读取每个源文件的数据并将其写入目标文件。通常不建议使用此选项,因为它通常会对像FIFO和通常在 /dev 目录中找到的特殊文件产生不良影响。在大多数情况下,cp -R --copy-contents 将无限期地挂起,尝试从FIFO和像 /dev/console 这样的特殊文件中读取,并且如果使用它来复制 /dev/zero,则会填满目标文件系统。此选项仅在递归复制时有效,并且不影响符号链接的复制。


‘-d’

将符号链接作为符号链接复制,而不是复制它们所指向的文件,并在副本中保留源文件之间的硬链接。等同于 --no-dereference --preserve=links。


‘--debug’

向标准输出打印额外的信息,解释文件是如何被复制的。此选项隐含了 --verbose 选项。


‘-f’

‘--force’

当没有此选项进行复制且无法打开现有目标文件进行写入时,复制操作将失败。但是,使用 --force 时,当无法打开目标文件时,cp 将尝试通过首先删除该文件来重新创建它。请注意,--force 单独使用不会删除悬空的符号链接。当此选项与 --link (-l) 或 --symbolic-link (-s) 结合使用时,目标链接将被替换,并且除非给出 --backup (-b),否则目标文件将不存在。


此选项与 --interactive 或 -i 选项无关:它们互不取消对方的效果。


当同时使用 --no-clobber 或 -n 选项时,此选项将被忽略。


‘-H’

如果命令行参数指定一个符号链接,则复制它所指向的文件,而不是复制符号链接本身。但是,通过递归遍历遇到的任何符号链接都会被复制(保持其性质)。


‘-i’

‘--interactive’

在复制除目录以外的文件时,提示是否覆盖现有目标文件,如果回答不是肯定的,则操作失败。-i 选项会覆盖之前的 -n 选项。


‘-l’

‘--link’

创建硬链接而不是非目录文件的副本。


‘-L’

‘--dereference’

复制时跟随符号链接。使用此选项,cp 无法创建符号链接。例如,源树中的符号链接(指向常规文件)将复制为目标树中的常规文件。


‘-n’

‘--no-clobber’

不要覆盖现有文件;如果文件已存在,则静默失败。此选项将覆盖之前的 -i 选项。此选项与 -b 或 --backup 选项互斥。


‘-P’

‘--no-dereference’

将符号链接作为符号链接复制,而不是复制它们所指向的文件。此选项仅影响源中的符号链接;如果可能,目标中的符号链接始终会被跟随。


‘-p’

‘--preserve[=attribute_list]’

保留原始文件的指定属性。如果指定了 attribute_list,则它必须是一个逗号分隔的字符串列表,其中包含以下一个或多个字符串:


‘mode’

保留与访问权限相关的属性,包括文件模式位和(如果可能)访问控制列表(ACL)。ACL 保留是与系统相关的,并且当源和目标位于具有不同 ACL 格式(例如,NFSv4 与 POSIX 格式)的文件系统上时,不一定会转换 ACL。


‘ownership’

保留所有者和组。在大多数现代系统上,只有具有适当特权的用户才能更改文件的所有者,普通用户只有在他们恰好是所需组的成员时才能保留文件的组所有权。


‘timestamps’

尽可能保留上次访问和上次修改的时间。在旧系统上,当受影响的文件是符号链接时,无法保留这些属性。然而,许多系统现在提供了 utimensat 函数,即使对于符号链接也可以实现这一点。


‘links’

在目标文件中保留任何对应源文件之间的链接。请注意,使用 -L 或 -H,此选项可以将符号链接转换为硬链接。例如,

$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
74161745 a
74161745 b

请注意输入:b 是指向常规文件 a 的符号链接,但目标目录 c/ 中的文件是硬链接。由于 -a 隐含了 --no-dereference,它会复制符号链接,但稍后的 -H 告诉 cp 对命令行参数进行解引用,然后它会看到两个具有相同 inode 号的文件。然后由 -a 隐含的 --preserve=links 选项将保留所感知的硬链接。

这是一个类似的示例,演示了 cp 的 -L 选项:

$ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b
74163295 a
74163295 b


‘context’

保留文件的 SELinux 安全上下文,否则打印完整的诊断信息。


‘xattr’

保留文件的扩展属性,否则打印完整的诊断信息。如果 cp 是没有 xattr 支持构建的,则忽略此选项。如果 SELinux 上下文、ACL 或能力是使用 xattr 实现的,则此选项也会隐式保留它们,即使没有指定 --preserve=mode 或 --preserve=context。


‘all’

保留所有文件属性。相当于指定上述所有选项,但区别在于无法保留 SELinux 安全上下文或扩展属性不会更改 cp 的退出状态。与 -a 不同,除了‘Operation not supported’警告之外,都会输出。

在没有此选项的情况下,现有目标文件的权限保持不变。每个新文件的创建模式是对应源文件的模式减去设置用户 ID、设置组 ID 和粘滞位;然后操作系统应用 umask 或默认 ACL,可能导致更严格的文件模式。请参阅文件权限。


‘--no-preserve=attribute_list’

不保留指定的属性。attribute_list的格式与--preserve相同。


‘--parents’

通过将目标目录和源文件的指定名称连接起来形成每个目标文件的名称。cp的最后一个参数必须是现有目录的名称。例如,命令:

cp --parents a/b/c existing_dir

将文件a/b/c复制到existing_dir/a/b/c,并创建任何缺失的中间目录。


‘-R’

‘-r’

‘--recursive’

递归复制目录。默认情况下,不会跟随源中的符号链接,除非与--link(-l)选项一起使用;参见--archive(-a)、-d、--dereference(-L)、--no-dereference(-P)和-H选项。特殊文件通过创建与源文件类型相同的目标文件来复制;参见--copy-contents选项。使用-r复制符号链接或特殊文件是不可移植的。在一些非GNU系统上,由于历史原因,-r隐含了-L和--copy-contents的等效操作。除非同时指定-P,否则使用-R复制符号链接也是不可移植的,因为POSIX允许默认解引用符号链接的实现。


‘--reflink[=when]’

执行轻量级的写时复制(COW)复制,如果文件系统支持。一旦成功,要注意源文件和目标文件共享相同的数据块,只要它们保持不变。因此,如果I/O错误影响到其中一个文件的数据块,另一个文件也会受到同样的影响。


when的值可以是以下之一:

‘always’:如果不支持写时复制操作,则对每个文件报告失败并以失败状态退出。纯粹的--reflink等效于--reflink=always。

‘auto’:如果不支持写时复制操作,则回退到标准复制行为。如果没有给出--reflink选项,则默认为此选项。

‘never’:禁用写时复制操作并使用标准复制行为。


此选项会被--link、--symbolic-link和--attributes-only选项覆盖,因此可以用于配置cp的默认数据复制行为。


‘--remove-destination’

在尝试打开每个现有目标文件之前删除它(与上面的-f相反)。


‘--sparse=when’

稀疏文件包含空洞-一系列不占用任何文件系统块的零字节;‘read’系统调用将其读取为零。这既可以节省大量空间,又可以提高速度,因为许多二进制文件包含大量连续的零字节。默认情况下,cp通过一个简单的启发式方法检测输入源文件中的空洞,并将相应的输出文件也设置为稀疏文件。只有常规文件可以是稀疏文件。


when的值可以是以下之一:

‘auto’:默认行为:如果输入文件是稀疏的,则尝试将输出文件也设置为稀疏文件。但是,如果存在一个输出文件但是指向非常规文件,则不尝试将其设置为稀疏文件。

‘always’:对于输入文件中的每个足够长的零字节序列,尝试在输出文件中创建相应的空洞,即使输入文件似乎不是稀疏文件。当输入文件位于不支持稀疏文件的文件系统上(例如SGI IRIX 5.3及更早版本的‘efs’文件系统),但输出文件位于支持稀疏文件的文件系统上时,这是有用的。空洞只能在常规文件中创建,因此如果目标文件是其他类型的文件,则cp甚至不会尝试将其设置为稀疏文件。

‘never’:永远不要将输出文件设置为稀疏文件。这在创建用于mkswap命令的文件时很有用,因为这样的文件不能有任何空洞。


例如,使用以下别名,cp将使用文件系统支持的最小空间量(旧版本的cp在这里也可以受益于--reflink=auto)。

alias cp='cp --sparse=always'


‘--strip-trailing-slashes’

从每个源参数中删除任何尾随斜杠。


‘-s’

‘--symbolic-link’

创建符号链接而不是非目录文件的副本。除非目标文件在当前目录中,否则所有源文件名必须是绝对路径(以‘/’开头)。在不支持符号链接的系统上,此选项只会导致错误消息。


‘-S suffix’

‘--suffix=suffix’

在使用-b进行备份时,将后缀添加到每个备份文件中。


‘-t directory’

‘--target-directory=directory’

指定目标目录。


‘-T’

‘--no-target-directory’

当最后一个操作数是目录或指向目录的符号链接时,不特殊处理它。


‘-u’

‘--update[=which]’

不复制具有与现有目标相同或更新的修改时间戳的非目录文件;而是静默跳过文件而不失败。如果保留时间戳,则比较的是截断为目标文件系统和用于更新时间戳的系统调用的分辨率的源时间戳;这样可以避免在使用相同的源和目标执行多个‘cp -pu’命令时重复工作。如果还指定了-n或--no-clobber选项,则忽略此选项。此外,如果还指定了--preserve=links(例如‘cp -au’),那么它将优先,因此,根据从源处理文件的顺序,目标中的较新文件可能会被替换,以镜像源中的硬链接。


which可以更好地控制替换目标中的现有文件,其值可以是以下之一:

‘all’:这是未指定--update选项时的默认操作,导致替换目标中的所有现有文件。

‘none’:类似于--no-clobber选项,即不替换目标中的任何文件,但跳过文件不会导致失败。

‘older’:这是指定了--update时的默认操作,导致替换文件,如果它们比相应的源文件旧。


‘-v’

‘--verbose’

在复制文件之前打印每个文件的名称。


‘-x’

‘--one-file-system’

跳过与复制开始的文件系统不同的子目录。但是,挂载点目录会被复制。


‘-Z’

‘--context[=context]’

如果没有指定上下文,则根据目标文件的系统默认类型调整SELinux安全上下文,类似于restorecon命令。如果指定了具体的上下文的长格式选项,将仅为新创建的文件设置上下文。如果同时禁用了SELinux和SMACK,则会发出警告。此选项与--preserve=context选项互斥,并覆盖--preserve=all和-a选项。


退出状态为零表示成功,非零值表示失败。