title: Linux(2)命令与文件操作date: 2021-05-29 17:25:29.008

updated: 2021-05-30 00:32:18.645
url: /?p=190
categories: Linux
tags: Linux

Linux “一切皆文件”。

Linux文件(目录)命名规则

Linux 系统中,文件和目录的命名规则如下:

  • 除了字符“/”之外,所有的字符都可以使用,但是要注意,在目录名或文件名中,使用某些特殊字符并不是明智之举。例如,在命名时应避免使用 <、>、?、* 和非打印字符等。如果一个文件名中包含了特殊字符,例如空格,那么在访问这个文件时就需要使用引号将文件名括起来。
  • 目录名或文件名的长度不能超过 255 个字符。
  • 目录名或文件名是区分大小写的。如 DOG、dog、Dog 和 DOg ,是互不相同的目录名或文件名,但使用字符大小写来区分不同的文件或目录,也是不明智的。
  • 与 Windows 操作系统不同,文件的扩展名对 Linux 操作系统没有特殊的含义,换句话说,Linux 系统并不以文件的扩展名开分区文件类型。例如,dog.exe 只是一个文件,其扩展名 .exe 并不代表此文件就一定是可执行文件。

需要注意的是,在 Linux 系统中,硬件设备也是文件,也有各自的文件名称。Linux 系统内核中的 udev 设备管理器会自动对硬件设备的名称进行规范,目的是让用户通过设备文件的名称,就可以大致猜测处设备的属性以及相关信息。

udev 设备管理器会一直以进程的形式运行,并侦听系统内核发出的信号来管理位于 /dev 目录下的设备文件。

【Linux硬件设备文件名称】

硬件设备 文件名称
IDE设备 /dev/hd[a-d],现在的 IDE设备已经很少见了,因此一般的硬盘设备会以 /dev/sd 开头。
SCSI/SATA/U盘 /dev/sd[a-p],一台主机可以有多块硬盘,因此系统采用 a~p 代表 16 块不同的硬盘。
软驱 /dev/fd[0-1]
打印机 /dev/lp[0-15]
光驱 /dev/cdrom
鼠标 /dev/mouse
磁带机 /dev/st0 或 /dev/ht0

Linux命令分辨文件类型

1.
通过颜色辨别

使用ls命令,可以发现不同类型的文件的名字颜色并不一样,不多赘述。

2.
通过不同字符对应的文件类型

过颜色来区分文件类型,难免有些牵强,对于颜色不太敏感的读者来说,很容易搞错。Linux 中精确判断文件类型的方法,是通过文件本身所具有的属性进行判断。

每行代表一个文件或目录,其中第一个字符表示的就是文件的类型,其可能的取值以及表示的文件类型。

第一个字符 文件类型
- 普通文件,包括纯文本文件、二进制文件、各种压缩文件等。
d 目录,类似 Windows 系统中的文件夹。
b 块设备文件,就是保存大块数据的设备,比如最常见的硬盘。
c 字符设备文件,例如键盘、鼠标等。
s 套接字文件,通常用在网络数据连接,可以启动一个程序开监听用户的要求,用户可以通过套接字进行数据通信。
p 管道文件,其主要作用是解决多个程序同时存取一个文件所造成的错误。
l 链接文件,类似 Windows 系统中的快捷方式。

命令提示符

登录系统后,第一眼看到的内容是:

1
[root@localhost ~]#

这就是 Linux 系统的命令提示符。那么,这个提示符的含义是什么呢?

  • []:这是提示符的分隔符号,没有特殊含义。
  • root:显示的是当前的登录用户,笔者现在使用的是 root 用户登录。
  • @:分隔符号,没有特殊含义。
  • localhost:当前系统的简写主机名(完整主机名是 localhost.localdomain)。
  • ~:代表用户当前所在的目录,此例中用户当前所在的目录是家目录。
  • #:命令提示符,Linux 用这个符号标识登录的用户权限等级。如果是超级用户,提示符就是 #;如果是普通用户,提示符就是 $。

家目录

Linux 系统是纯字符界面,用户登录后,要有一个初始登录的位置,这个初始登录位置就称为用户的家:

  • 超级用户的家目录:/root。
  • 普通用户的家目录:/home/用户名。

命令的基本格式

接下来看看 Linux 命令的基本格式:

1
[root@localhost ~]# 命令[选项][参数]

命令的选项用于调整命令功能,而命令的参数是这个命令的操作对象。

  • 选项:Linux 的选项又分为短格式选项(-l)和长格式选项(–all)。短格式选项是英文的简写,用一个减号调用。
  • 参数:参数是命令的操作对象,一般文件、目录、用户和进程等可以作为参数被命令操作。

Linux文件操作常用命令

切换命令cd

cd命令,“change direction”的缩写。

1
2
3
4
5
6
7
cd dirname【进入目录】

cd .. 【返回上一级目录】

cd . 【就是在当前目录 相当于啥事都没有做了】

cd 【回到根目录】

显示当前路径 pwd

Pwd命令,“print working directory”的缩写,不是password,不是password。

1
pwd 【查看当前路径】

查看目录下文件ls

ls 命令,list 的缩写。

1
[root@localhost ~]# ls [选项] 目录名称

使用ls --help,查看选项信息。

1
2
3
4
5
ls 【大概目录】

ls -all 【详细目录】

ls -lh 【xxKB,详细目录】

创建文件夹 mkdir

mkdir 命令,是 make directories 的缩写。

mkdir 命令的基本格式为:

1
[root@localhost ~]# mkdir [-mp] 目录名
  • -m 选项用于手动配置所创建目录的权限,而不再使用默认权限。
  • -p 选项递归创建所有目录,以创建 /home/test/demo 为例,在默认情况下,你需要一层一层的创建各个目录,而使用 -p 选项,则系统会自动帮你创建 /home、/home/test 以及 /home/test/demo。
1
2
3
4
5
6
7
mkdir NDK24 【创建文件夹】

mkdir Android/NDK/ffmpeg 【无法创建目录】

mkdir -p Android/NDK/ffmpeg 【使用 -p 选项递归建立目录。】

mkdir -m 711 test2 【使用 -m 选项自定义目录权限】

删除空目录 rmdir

和 mkdir 命令(创建空目录)恰好相反,rmdir(remove empty directories 的缩写)命令用于删除空目录。(注意了,一定是删除空目录,一旦目录中有内容,就会报错。)

1
[root@localhost ~]# rmdir [-p] 目录名

-p 选项用于递归删除空目录。

创建文件及修改文件时间戳 touch

touch的意思是触摸触碰,很多人有疑惑,这翻译和创建文件没啥关系啊,为什么要使用touch。其实,touch的本意并不是创建文件。它最先表达的功能是修改文件的时间参数(但当文件存在时,会修改此文件的时间参数)。

关于修改文件时间:

touch: change file access and modification times (BSD)

touch: change file timestamps (GNU)

大概也就是摸一下,表示最近动过了。

关于创建:

A FILE argument that does not exist is created empty, unless -c or -h is supplied.(GUN touch –help)。

Linux 系统中,每个文件主要拥有 3 个时间参数(通过 stat 命令进行查看),分别是文件的访问时间、数据修改时间以及状态修改时间:

  • 访问时间(Access Time,简称 atime):只要文件的内容被读取,访问时间就会更新。例如,使用 cat 命令可以查看文件的内容,此时文件的访问时间就会发生改变。
  • 数据修改时间(Modify Time,简称 mtime):当文件的内容数据发生改变,此文件的数据修改时间就会跟着相应改变。
  • 状态修改时间(Change Time,简称 ctime):当文件的状态发生变化,就会相应改变这个时间。比如说,如果文件的权限或者属性发生改变,此时间就会相应改变。

touch 命令的基本格式如下:

1
[root@localhost ~]# touch [选项] 文件名

选项:

  • -a:只修改文件的访问时间;
  • -c:仅修改文件的时间参数(3 个时间参数都改变),如果文件不存在,则不建立新文件。
  • -d:后面可以跟欲修订的日期,而不用当前的日期,即把文件的 atime 和 mtime 时间改为指定的时间。
  • -m:只修改文件的数据修改时间。
  • -t:命令后面可以跟欲修订的时间,而不用目前的时间,时间书写格式为 YYMMDDhhmm

可以看到,touch 命令可以只修改文件的访问时间,也可以只修改文件的数据修改时间,但是不能只修改文件的状态修改时间。因为,不论是修改访问时间,还是修改文件的数据时间,对文件来讲,状态都会发生改变,即状态修改时间会随之改变(更新为操作当前文件的真正时间)

1
touch file01.txt 【创建文件】

建立硬链接和软链接文件,ln命令

参考:https://zhuanlan.zhihu.com/p/88891362

链接的原理

ln 命令用于给文件创建链接,根据 Linux 系统存储文件的特点,链接的方式分为以下 2 种:

  • 软链接:类似于 Windows 系统中给文件创建快捷方式,即产生一个特殊的文件,该文件用来指向另一个文件,此链接方式同样适用于目录。
  • 硬链接:我们知道,文件的基本信息都存储在 inode 中,而硬链接指的就是给一个文件的 inode 分配多个文件名,通过任何一个文件名,都可以找到此文件的 inode,从而读取该文件的数据信息。

ln 命令的基本格式如下:

1
[root@localhost ~]# ln [选项] 源文件 目标文件

选项:

  • -s:建立软链接文件。如果不加 “-s” 选项,则建立硬链接文件;
  • -f:强制。如果目标文件已经存在,则删除目标文件后再建立链接文件;

【例 1】创建硬链接:

1
2
3
4
[root@localhost ~]# touch cangls
[root@localhost ~]# ln /root/cangls /tmp
#建立硬链接文件,目标文件没有写文件名,会和原名一致
#也就是/tmp/cangls 是硬链接文件

【例 2】创建软链接:

1
2
3
[root@localhost ~]# touch bols
[root@localhost ~]# In -s /root/bols /tmp
#建立软链接文件

这里需要注意的是,软链接文件的源文件必须写成绝对路径,而不能写成相对路径(硬链接没有这样的要求);否则软链接文件会报错。这是初学者非常容易犯的错误。

对硬链接的深度剖析

首先,我们再来建立一个硬链接文件,然后看看这两个文件的特点。

1
2
3
4
5
6
7
8
9
[root@localhost ~]# touch test
#建立源文件
[root@localhost ~]# ln /root/test /tmp/test-hard
#给源文件建立硬链接文件 /tmp/test-hard
[root@localhost ~]# ll -i /root/test /tmp/test-hard
262147 -rw-r--r-- 2 root root 0 6月 19 10:06 /root/test
hard
262147 -rw-r--r-- 2 root root 0 6月 19 10:06 /tmp/test-hard
#查看两个文件的详细信息,可以发现这两个文件的 inode 号是一样的,"ll"等同于"ls -l"。

这里有一件很奇怪的事情,我们之前在讲 inode 号的时候说过,每个文件的 inode 号都应该是不一样的。inode 号就相当于文件 ID,我们在查找文件的时候,要先查找 inode 号,才能读取到文件的内容。

但是这里源文件和硬链接文件的 inode 号居然是一样的,那我们在查找文件的时候,到底找到的是哪一个文件呢?我们来画一张示意图,如图所示。

在 inode 信息中,是不会记录文件名称的,而是把文件名记录在上级目录的 block 中。也就是说,目录的 block 中记录的是这个目录下所有一级子文件和子目录的文件名及 inode 的对应;而文件的 block 中记录的才是文件实际的数据。

当我们查找一个文件,比如 /root/test 时,要经过以下步骤:

1.首先找到根目录的 inode(根目录的 inode 是系统已知的,inode 号是 2),然后判断用户是否有权限访问根目录的 block。

2.如果有权限,则可以在根目录的 block 中访问到 /root 的文件名及对应的 inode 号。

3.通过 /root/ 目录的 inode 号,可以查找到 /root/ 目录的 inode 信息,接着判断用户是否有权限访问 /root/ 目录的 block。

4.如果有权限,则可以从 /root/ 目录的 block 中读取到 test 文件的文件名及对应的 inode 号。

5.通过 test 文件的 inode 号,就可以找到 test 文件的 inode 信息,接着判断用户是否有权限访问 test 文件的 block。

6.如果有权限,则可以读取 block 中的数据,这样就完成了 /root/test 文件的读取与访问。

按照这个步骤,在给源文件 /root/test 建立了硬链接文件 /tmp/test-hard 之后,在 /root/ 目录和 /tmp/ 目录的 block 中就会建立 test 和 test-hard 的信息,这个信息主要就是文件名和对应的 inode 号。但是我们会发现 test 和 test-hard 的 inode 信息居然是一样的,那么,我们无论访问哪个文件,最终都会访问 inode 号是 262147 的文件信息。

这就是硬链接的原理。硬链接的特点如下:

  • 不论是修改源文件(test 文件),还是修改硬链接文件(test-hard 文件),另一个文件中的数据都会发生改变。
  • 不论是删除源文件,还是删除硬链接文件,只要还有一个文件存在,这个文件(inode 号是 262147 的文件)都可以被访问。
  • 硬链接不会建立新的 inode 信息,也不会更改 inode 的总数。
  • 硬链接不能跨文件系统(分区)建立,因为在不同的文件系统中,inode 号是重新计算的。
  • 硬链接不能链接目录,因为如果给目录建立硬链接,那么不仅目录本身需要重新建立,目录下所有的子文件,包括子目录中的所有子文件都需要建立硬链接,这对当前的 Linux 来讲过于复杂。

硬链接的限制比较多,既不能跨文件系统,也不能链接目录,而且源文件和硬链接文件之间除 inode 号是一样的之外,没有其他明显的特征。这些特征都使得硬链接并不常用,大家有所了解就好。

我们通过实验来测试一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@localhost ~]# echo 1111 >>/root/test
#向源文件中写入数据
[root@localhost ~]# cat /root/test
1111
[root@localhost ~]# cat /tmp/test-hard
1111
#源文件和硬链接文件都会发生改变
[root@localhost ~]# echo 2222 >> /tmp/test-hard
#向硬链接文件中写入数据
[root@localhost ~]# cat /root/test
1111
2222
[root@localhost ~】# cat /tmp/test-hard
1111
2222
#源文件和硬链接文件也都会发生改变
[root@localhost ~]# rm -rf/root/test
#删除源文件
[root@localhost ~]# cat /tmp/test-hard
1111 2222
#硬链接文件依然可常读取

对软链接的深度剖析

软链接也称作符号链接,相比硬链接来讲,软链接就要常用多了。我们先建立一个软链接,再来看看软链接的特点。

1
2
3
4
5
6
7
8
9
[root@localhost ~]# touch check
#建立源文件
[root@localhost ~]# ln -s /root/check /tmp/check-soft
#建立软链接文件
[root@localhost ~]# ll -id /root/check /tmp/check-soft
262154 -rw-r--r-- 1 root root 0 6月 19 11:30 /root/check
917507 lrwxrwxrwx 1 root root 11 6月 19 11:31 /tmp/ check-soft -> /root/check
#软链接和源文件的 inode 号不一致,软链接通过 -> 明显地标识出源文件的位置
#在软链接的权限位 lrwxrwxrwx 中,l 就代表软链接文件

再强调一下,软链接的源文件必须写绝对路径,否则建立的软链接文件就会报错,无法正常使用。

软链接的标志非常明显,首先,权限位中”l”表示这是一个软链接文件;其次,在文件的后面通过 “->” 显示出源文件的完整名字。所以软链接比硬链接的标志要明显得多,而且软链接也不像硬链接的限制那样多,比如软链接可以链接目录,也可以跨分区来建立软链接。

软链接完全可以当作 Windows 的快捷方式来对待,它的特点和快捷方式一样,我们更推荐大家使用软链接,而不是硬链接。

大家在学习软链接的时候会有一些疑问:Windows 的快捷方式是由于源文件放置的位置过深,不容易找到,建立一个快捷方式放在桌面,方便查找,那 Linux 的软链接的作用是什么呢?

软链接主要是为了照顾管理员的使用习惯。比如,有些系统的自启动文件 /etc/rc.local 放置在 /etc 目录中,而有些系统却将其放置在 /etc/rc.d/rc.local 中,那么干脆对这两个文件建立软链接,不论你习惯操作哪一个文件,结果都是一样的。

如果你比较细心,则应该已经发现软链接和源文件的 inode 号是不一致的,我们也画一张示意图来看看软链接的原理,如图所示。

软链接和硬链接的区别

软链接和硬链接在原理上最主要的不同在于:硬链接不会建立自己的 inode 索引和 block(数据块),而是直接指向源文件的 inode 信息和 block,所以硬链接和源文件的 inode 号是一致的;而软链接会真正建立自己的 inode 索引和 block,所以软链接和源文件的 inode 号是不一致的,而且在软链接的 block 中,写的不是真正的数据,而仅仅是源文件的文件名及 inode 号。

我们来看看访问软链接的步骤和访问硬链接的步骤有什么不同。

  1. 首先找到根目录的 inode 索引信息,然后判断用户是否有权限访问根目录的 block。
  2. 如果有权限访问根目录的 block,就会在 block 中查找到 /tmp/ 目录的 inode 号。
  3. 接着访问 /tmp/ 目录的 inode 信息,判断用户是否有权限访问 /tmp/ 目录的 block。
  4. 如果有权限,就会在 block 中读取到软链接文件 check-soft 的 inode 号。因为软链接文件会真正建立自己的 inode 索引和 block,所以软链接文件和源文件的 inode 号是不一样的。
  5. 通过软链接文件的 inode 号,找到了 check-soft 文件 inode 信息,判断用户是否有权限访问 block。
  6. 如果有权限,就会发现 check-soft 文件的 block 中没有实际数据,仅有源文件 check 的 inode 号。
  7. 接着通过源文件的 inode 号,访问到源文件 check 的 inode 信息,判断用户是否有权限访问 block。
  8. 如果有权限,就会在 check 文件的 block 中读取到真正的数据,从而完成数据访问。

通过这个过程,我们就可以总结出软链接的特点(软链接的特点和 Windows 中的快捷方式完全一致)。

  • 不论是修改源文件(check),还是修改硬链接文件(check-soft),另一个文件中的数据都会发生改变。
  • 删除软链接文件,源文件不受影响。而删除原文件,软链接文件将找不到实际的数据,从而显示文件不存在。
  • 软链接会新建自己的 inode 信息和 block,只是在 block 中不存储实际文件数据,而存储的是源文件的文件名及 inode 号。
  • 软链接可以链接目录。
  • 软链接可以跨分区。

我们测试一下软链接的特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@localhost ~]# echo 111>>/root/check
#修改源文件
[root@localhost ~]# cat /root/check
111
[root@localhost ~]# cat /tmp/check-soft
111
#不论是源文件还是软链接文件,数据都发生改变
[root@localhost ~]# echo 2222 >>/tmp/check-soft
#修改软链接文件
[root@localhost ~]# cat /tmp/check-soft
111
2222
[root@localhost ~]# cat /root/check
111
2222
#不论是源文件还是软链接文件,数据也都会发生改变
[root@localhost ~]# rm -rf/root/check
#删除源文件
[root@localhost ~]# cat /tmp/check-soft
cat: /tmp/check-soft:没有那个文件或目录
#软链接无法正常使用

软链接是可以链接目录的,例如:

1
2
3
4
5
6
[root@localhost ~]# mkdir test
#建立源目录
[root@localhost ~]# ln -s /root/test/ /tmp/
[root@localhost ~]# ll -d /tmp/test
lrwxrwxrwx 1 root root 11 6月 19 12:43 /tmp/test->/root/test/
#软链接可以链接目录

cp命令 复制文件和目录

cp 命令的基本格式如下:

1
[root@localhost ~]# cp [选项] 源文件 目标文件

选项:

  • -a:相当于 -d、-p、-r 选项的集合,这几个选项我们一一介绍;
  • -d:如果源文件为软链接(对硬链接无效),则复制出的目标文件也为软链接;
  • -i:询问,如果目标文件已经存在,则会询问是否覆盖;
  • -l:把目标文件建立为源文件的硬链接文件,而不是复制源文件;
  • -s:把目标文件建立为源文件的软链接文件,而不是复制源文件;
  • -p:复制后目标文件保留源文件的属性(包括所有者、所属组、权限和时间);
  • -r:递归复制,用于复制目录;
  • -u:若目标文件比源文件有差异,则使用该选项可以更新目标文件,此选项可用于对文件的升级和备用。

需要注意的是,源文件可以有多个,但这种情况下,目标文件必须是目录才可以。

rm命令:删除文件或目录

rm 是强大的删除命令,它可以永久性地删除文件系统中指定的文件或目录。在使用 rm 命令删除文件或目录时,系统不会产生任何提示信息。此命令的基本格式为:

1
[root@localhost ~]# rm[选项] 文件或目录

选项:

  • -f:强制删除(force),和 -i 选项相反,使用 -f,系统将不再询问,而是直接删除目标文件或目录。
  • -i:和 -f 正好相反,在删除文件或目录之前,系统会给出提示信息,使用 -i 可以有效防止不小心删除有用的文件或目录。
  • -r:递归删除,主要用于删除目录,可删除指定目录及包含的所有内容,包括所有的子目录和文件。

注意,rm 命令是一个具有破坏性的命令,因为 rm 命令会永久性地删除文件或目录,这就意味着,如果没有对文件或目录进行备份,一旦使用 rm 命令将其删除,将无法恢复,因此,尤其在使用 rm 命令删除目录时,要慎之又慎。

mv命令:移动文件或重命名

mv 命令(move 的缩写),既可以在不同的目录之间移动文件或目录,也可以对文件和目录进行重命名。该命令的基本格式如下:

1
[root@localhost ~]# mv 【选项】 源文件 目标文件

选项:

  • -f:强制覆盖,如果目标文件已经存在,则不询问,直接强制覆盖;
  • -i:交互移动,如果目标文件已经存在,则询问用户是否覆盖(默认选项);
  • -n:如果目标文件已经存在,则不会覆盖移动,而且不询问用户;
  • -v:显示文件或目录的移动过程;
  • -u:若目标文件已经存在,但两者相比,源文件更新,则会对目标文件进行升级;

需要注意的是,同 rm 命令类似,mv 命令也是一个具有破坏性的命令,如果使用不当,很可能给系统带来灾难性的后果。