要在基于 Unix 的操作系统(Linux 和 MacOS)中复制文件或目录,需要使用 cp 命令。

cp 命令是一个相对简单的命令,但是其输出会根据输入(文件或目录)和传递给它的选项而略有变化。

要查看 cp 命令的文档或手册,请在终端上运行 man cp

$ man cp

NAME
     cp -- copy files

SYNOPSIS
     cp [OPTIONS] source_file target_file
     cp [OPTIONS] source_file ... target_directory

...

这个命令的基本形式包括要复制的一个或多个输入源(文件或目录),以及将文件或目录复制到什么目标位置:

cp [OPTIONS] source_file target_file

如何将文件复制到当前目录

要复制文件,需要输入要复制的文件以及要将文件复制到什么目标路径。

如果你有一个名为 a.txt 的文件,想要给该文件生成一个副本,名为 b.txt

$ ls
a.txt

$ cp a.txt b.txt

$ ls
a.txt   b.txt
如果你不熟悉 ls 命令,这个命令是“列出”目录的所有内容。

默认情况下,cp 命令使用你的当前目录作为路径。

如何将文件复制到另一个目录

要将文件复制到与当前目录不同的目录,你只需要输入另一个目录的路径作为目标即可:

$ ls ../directory-1/

$ cp a.txt ../directory-1/

$ ls ../directory-1/
a.txt

执行 cp 命令之后,之前空的 directory-1 现在包含了文件 a.txt

默认情况下,复制文件的名称和原始文件的名称相同,但是你也可以选择定义文件名:

$ cp a.txt ../directory-1/b.txt

$ ls ../directory-1/
b.txt

如何将多个文件复制到一个目录

要一次复制多个文件,可以输入多个输入源和一个目录作为目标路径:

$ ls ../directory-1/

$ cp first.txt second.txt ../directory-1/

$ ls ../directory-1/
first.txt       second.txt

这里,两个文件(first.txtsecond.txt)都被复制到目录 directory-1

注意当传递多个原文件时,最后一个参数必须是目录。

如何将一个目录复制到另一个目录

如果你尝试传递一个目录作为输入源,将显示错误:

$ cp directory-1 directory-2
cp: directory-1 is a directory (not copied).

要复制一个目录,需要添加 -r(或 -R)标记——即 --recursive 的简写:

$ ls directory-1
a.txt

$ cp -r directory-1 directory-2

$ ls
directory-1          directory-2

$ ls directory-2
a.txt

这里,包含文件 a.txtdirectory-1 被复制到一个新的目录,directory-2——现在也包含文件 a.txt

如何复制整个目录或目录的内容

复制目录时有一个有趣的情况:如果目标目录已经存在,则可以通过在输入的末尾添加或删除 / 来选择复制目录的内容还是整个目录

这是 man 页面的 -R 选项的描述:

如果 source_file 指定一个目录,则 cp 命令复制该目录以及此时连接的整个子树。 如果 source_file 以 / 结尾,则复制目录的内容,而不是目录本身。

如果仅将目录的内容复制到另一个目录,则在输入末尾添加 /

如果要将目录的内容和目录文件夹本身复制到另一个目录,则不需要在输入的末尾添加 /

$ ls
directory-1          directory-2

$ ls directory-2

$ cp -r directory-1 directory-2

$ ls directory-2
directory-1

$ ls directory-2/directory-1
a.txt

在这里,你可以看到,因为 directory-2 已经存在——输入末尾没有 /——directory-1 的内容目录本身都被复制到目标文件夹中。

如何避免 cp 命令重写文件

默认情况下,cp 命令将重写已有的文件:

$ cat a.txt
A

$ cat directory-1/a.txt
B

$ cp a.txt directory-1/a.txt

$ cat directory-1/a.txt
A
如果你熟悉 cat 或者 “concatenate” 命令,它打印一个文件的内容。

有两种方式避免这种情况。

interactive 标记

可以添加 -i--interactive 标记,在即将重写时给予提示:

$ cp -i a.txt directory-1/a.txt
overwrite directory-1/a.txt? (y/n [n])

no-clobber 标记

或者使用 -n--no-clobber 标记,在没有提示的情况下避免重写:

$ cat a.txt
A

$ cat directory-1/a.txt
B

$ cp -n a.txt directory-1/a.txt

$ cat directory-1/a.txt
B

这里,你可以看到,因为有 -n 标记,directory-1/a.txt 的内容未被重写:

其他选项

cp 命令还可以搭配很多其他有用的选项一起使用:-v 用于显示“详细”的输出,-f 用于“强制”。

我强烈建议你通读 man 页面,以了解所有其他有用的选项。

如果你喜欢本教程,我还将在 Twitter 上谈论类似的主题,并在我的网站上写关于这些主题的文章,欢迎访问。

原文:Copy a Directory in Linux – How to cp a Folder in the Command Line in Linux and Unix (MacOS),作者:John Mosesman