复制、移动与删除

cp 复制

复制文件用 cp(copy),先写源文件,再写新文件名或目标目录。我们把 notes.txt 复制一份叫 notes-copy.txt:

crow@opsbox:~/work$ cp notes.txt notes-copy.txt
crow@opsbox:~/work$ ls
notes-copy.txt
notes.txt
vim-notes.txt
crow@opsbox:~/work$ cat notes-copy.txt
阅读六月交接记录。

复制出来的文件是独立的副本,改其中一个不会影响另一个。如果要复制整个目录,需要加上 -r(递归)选项,比如 cp -r archive archive-backup。

mv 移动与重命名

移动文件用 mv(move),同样是先写源文件、再写目标位置。先建一个 archive 目录,再把 notes-copy.txt 移进去:

crow@opsbox:~/work$ mkdir archive
crow@opsbox:~/work$ mv notes-copy.txt archive/
crow@opsbox:~/work$ ls
archive
notes.txt
vim-notes.txt
crow@opsbox:~/work$ ls archive
notes-copy.txt

mv 还能用来重命名——只要第二个参数写一个新名字,文件就会直接改名。也可以把移动和改名合在一步里完成:

crow@opsbox:~/work$ mv archive/notes-copy.txt archive/notes-june.txt
crow@opsbox:~/work$ ls archive
notes-june.txt

复制保留原文件,移动让副本出现在另一个位置

file 鉴别文件类型

平时用电脑时,我们习惯看后缀名认文件(.txt 是文本、.jpg 是图片)。但在 Linux 里,后缀名只是名字的一部分,把一段文本或脚本改名叫 .jpg,它也不会变成真图片。要看一个文件到底是什么格式,可以用 file 命令:

crow@opsbox:~/work$ file notes.txt
notes.txt: Unicode text, UTF-8 text

我们把纯文本的 notes.txt 复制一份叫 sample.jpg,再用 file 测一下:

crow@opsbox:~/work$ cp notes.txt sample.jpg
crow@opsbox:~/work$ file sample.jpg
sample.jpg: Unicode text, UTF-8 text

哪怕名字改成了 .jpg,file 依然认出它是 UTF-8 文本。这是因为大多数文件格式都会在最开头的几个字节写入固定的二进制标识,叫作文件头魔数(Magic Number)——比如真 JPEG 开头总是 FF D8 FF E0,PNG 开头总是 89 50 4E 47,Linux 可执行程序(ELF)开头是 7F 45 4C 46。file 直接检查文件头和内容特征,不会被假后缀骗过去。

去 opsbox 上用 file 找一找混在扫描件图片里的文本文件:

混在图片里的文件

Lab

启动实验并打开 OPSBOX 终端:OPSBOX 终端(启动 Lab 后显示)。 /srv/ops/practice/scans 目录中有五个扫描件,名字都以 .jpg 结尾,但其中一个其实不是图片。 用 file 找出它,读取它的内容,提交其中的登记编号。

加载会话状态…

提交 coin

题解 Hint

rm 删除

删除文件用 rm(remove)。加上 -i 选项可以让它在删之前先问一句:

crow@opsbox:~/work$ rm -i sample.jpg
rm: remove regular file 'sample.jpg'? y
crow@opsbox:~/work$ ls
archive
notes.txt
vim-notes.txt

不加 -i 时,rm 会直接删掉文件,而且命令行里删掉的文件不进回收站。

rm 默认不能删目录,直接敲 rm archive 会报错 Is a directory。要连同目录里的内容一起删掉,需要加 -r(如 rm -r archive);如果再加上 -f(写成 rm -rf),则会跳过所有确认强制删除。

警告

网上常有人拿 rm -rf / 开玩笑,骗新手说是“清理缓存”或“修复系统”。它会从根目录开始删光系统里能删的一切。千万不要运行来路不明的删除命令,自己敲 rm -rf 前也要先看清路径。

ln 创建软链接与硬链接

有时我们想在某个目录放一个指向别处文件的“快捷方式”,这在 Linux 里叫链接(Link),分软链接和硬链接两种。

先复制一个文件作为目标,再用 ln -s 创建指向它的软链接(Symbolic Link):

crow@opsbox:~/work$ cp notes.txt link-source.txt
crow@opsbox:~/work$ ln -s link-source.txt shortcut.txt
crow@opsbox:~/work$ ls -l shortcut.txt
lrwxrwxrwx 1 crow crow 15 Sep  8 12:30 shortcut.txt -> link-source.txt
crow@opsbox:~/work$ cat shortcut.txt
阅读六月交接记录。

ls -l 最左边的 l 表示软链接,末尾的 -> link-source.txt 标出了它指向的目标。注意它的大小只有 15 字节,刚好是 link-source.txt 这串文件名的长度——因为软链接自己只是一个存着目标路径字符串的小文件。一旦把原文件移走或删掉,软链接就会失效:

crow@opsbox:~/work$ mv link-source.txt archive/link-source.txt
crow@opsbox:~/work$ cat shortcut.txt
cat: shortcut.txt: No such file or directory

如果不加 -s 直接运行 ln,创建的就是硬链接(Hard Link)。在 Linux 磁盘上,文件真正的数据和元信息保存在编号唯一的 Inode(索引节点) 里,而文件名只是指向某个 Inode 编号的标签。我们给 archive/link-source.txt 建一个硬链接 same-file.txt,并用 ls -li 查看它们的 Inode 编号:

crow@opsbox:~/work$ ln archive/link-source.txt same-file.txt
crow@opsbox:~/work$ ls -li archive/link-source.txt same-file.txt
131084 -rw-r--r-- 2 crow crow 28 Sep  8 12:30 archive/link-source.txt
131084 -rw-r--r-- 2 crow crow 28 Sep  8 12:30 same-file.txt

两行最左边的 Inode 编号都是 131084,硬链接计数变成了 2。也就是说,same-file.txt 和原文件是直接指向同一份底层数据的两个平等文件名。哪怕把原来的 archive/link-source.txt 删掉,只要计数没归零,数据就还在,cat same-file.txt 照样能读出来。

符号链接记录目标路径,硬链接的两个名称指向同一个文件