# 文件与目录管理
# 文件与木的检视 ls
ls [-aAdfFhilnrRSt] 文件名或目录名称Â
ls [--color={never,auto,always}] 文件名或目录名称
ls [--full-time] 文件名或目录名称
2
3
选项与参数:
a:全部的文件,连同隐藏文件(开头为 .)一起列出来(常用)
A:全部的文件,连同隐藏文件(不包括 . 和 .. 这两个目录)
d:仅列出目录本身,而不是列出目录内的文件数据(常用)
f:直接列出结果,而不进行排序(ls 默认以文档名排序)
F:根据文件、目录等信息,给予附加数据结构
如:
*
代表可执行文件,/
代表目录=
代表 socket 文件|
代表 FIFO 文件
# 如这样,会在文件名后面显示符号 [mrcode@study ~]$ ls -F 下载/ 公共/ 图片/ 文档/ 桌面/ 模板/ 视频/ 音乐/
1
2
3h:将文件容量以人类较易读的方式(例如 GB、KB)列出来
i:列出 inode 号码,inode 的意义后续讲解
l:长数据串输出,包含文件的属性与权限等数据(常用)
n:列出 UID 与 GID 而非使用者与群组的名称(UID 与 GID 会在账户管理中讲解)
r:将排序结果反向输出,例如原本文件名由小到大,反向则由大到小
R:连同子目录内容一起列出来,等于该目录下的所有文件都会显示出来
S:按文件容量大小排序
t:按时间排序
color 颜色配置
- never:不要依据文件特性给予颜色显示
- always:显示颜色
- auto:让系统自行依据设置来判断是否给予颜色
full-time:以完整时间模式)包含年月日时分输出
time={atime,ctime}
:输出 access 时间或改变权限属性时间(ctime),而非内容变更时间
在 linux 中 ls 指令可能是 最常用的,由于文件所记录的信息实在是太多了, 所以默认显示的只有:非隐藏文档、以文件名进行排序、文件名代表的颜色显示
实践练习
# 将家目录下的所有问价列出来,包含属性与隐藏文件
[mrcode@study ~]$ ls -al ~
total 40
drwx------. 18 mrcode mrcode 4096 Oct 8 23:15 . # 深蓝色
drwxr-xr-x. 4 root root 42 Oct 8 23:01 .. # 深蓝色
-rw-------. 1 mrcode mrcode 2927 Oct 11 05:16 .bash_history
-rw-r--r--. 1 mrcode mrcode 18 Aug 8 20:06 .bash_logout
-rw-r--r--. 1 mrcode mrcode 193 Aug 8 20:06 .bash_profile
-rw-r--r--. 1 mrcode mrcode 231 Aug 8 20:06 .bashrc
drwx------. 16 mrcode mrcode 4096 Oct 4 21:33 .cache # 深蓝色
# 接上题,不显示颜色,但在文件名末尾显示该文件名代表的类型
# 实际的终端中看,颜色就没显示了
[mrcode@study ~]$ ls -alF --color=never ~
total 40
drwx------. 18 mrcode mrcode 4096 Oct 8 23:15 ./
drwxr-xr-x. 4 root root 42 Oct 8 23:01 ../
-rw-------. 1 mrcode mrcode 2927 Oct 11 05:16 .bash_history
-rw-r--r--. 1 mrcode mrcode 18 Aug 8 20:06 .bash_logout
-rw-r--r--. 1 mrcode mrcode 193 Aug 8 20:06 .bash_profile
-rw-r--r--. 1 mrcode mrcode 231 Aug 8 20:06 .bashrc
drwx------. 16 mrcode mrcode 4096 Oct 4 21:33 .cache/
# 显示完整的修改实践(modification time)
[mrcode@study ~]$ ls -al --full-time ~
total 40
drwx------. 18 mrcode mrcode 4096 2019-10-08 23:15:44.109000000 +0800 .
drwxr-xr-x. 4 root root 42 2019-10-08 23:01:04.516000000 +0800 ..
-rw-------. 1 mrcode mrcode 2927 2019-10-11 05:16:27.662000000 +0800 .bash_history
-rw-r--r--. 1 mrcode mrcode 18 2019-08-08 20:06:55.000000000 +0800 .bash_logout
-rw-r--r--. 1 mrcode mrcode 193 2019-08-08 20:06:55.000000000 +0800 .bash_profile
-rw-r--r--. 1 mrcode mrcode 231 2019-08-08 20:06:55.000000000 +0800 .bashrc
drwx------. 16 mrcode mrcode 4096 2019-10-04 21:33:12.075000000 +0800 .cache
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
可以看到 ls 支持的功能很多,这些都是因为 linux 文件系统记录了很多有用的信息的缘故, 那么这些与权限、属性有关的数据放在 i-node 里面的。后续会深入讲解 i-node 的
另外,由于 ls -l 使用频率很高,为此,很多 distribution 在预设情况中已经将 ll 设定为 ls -l 的意思了。
# 复制、删除与移动:cp、rm、mv
- cp:copy 复制文件,该指令还有其他功能,如建立连接档、比较亮文件的新旧而给予更新,复制整个目录等功能
- mv:move 移动目录与文件,也可以直接拿来当做更名(rename)
- rm:remove 移除文件
# cp 复制文件或目录
cp [-adfilprsu] 来源文件(source)目标文件(destination)
cp [options] source1 source2 source3 .... directory
2
选项与参数:
- a:相当于 -dr --preserve=all 的一是一,至于 dr 请参考下列说明;(常用)
- d:若来源文件为链接文件的属性(link file),则复制链接文件属性而非文件本身
- f:强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次
- i:若目标文件已经存在时,在覆盖时会先询问动作的进行。(常用)
- l:进行硬式链接(hard link)的链接档的建立,而非复制文件本身
- p:连同文件的属性(权限、用户、时间)一起复制过去,而非使用默认属性;(备份文件常用)
- r:递归持续复制,用于目录的复制行为。(常用)
- s:复制称为符号链接文件(symbolic link)
- u:destination 与 source 旧才更新 destination,或 destination 不存在的情况下才复制
--preserve=all
:除了 -p 的权限相关参数外,还加入 SELinux 的属性,links、xattr 等也复制
最后需要注意的是:如果来源档有两个以上,则最后一个目的文件一定要是目录才行
而且不同身份者执行这个指令会有不同的结果产生,尤其是 -a、-p 的选项,对于不同身份来说, 差异则非常的大。
实践练习
# 使用 root 身份,将家目录下的 .bashrc 复制到 /tmp 下,并更名为 bashrc
[root@study ~]# cp ~/.bashrc /tmp/bashrc
# 加上 -i 属性,由于上面已经复制过一次了,所以 bashrc 文件已经存在
[root@study ~]# cp -i ~/.bashrc /tmp/bashrc
cp:是否覆盖"/tmp/bashrc"? # n 不覆盖,y 覆盖
# 变换目录到 /tmp ,并将 /var/log/wtmp 复制到 /tmp 且观察属性
[root@study tmp]# cd /tmp/
[root@study tmp]# cp /var/log/wtmp .
# ls 可以列出多个文档名,这里列出了两个,刚好可以对比他们的属性
[root@study tmp]# ls -l /var/log/wtmp wtmp
-rw-rw-r--. 1 root utmp 44160 10月 13 14:38 /var/log/wtmp
-rw-r--r--. 1 root root 44160 10月 13 15:42 wtmp
# 可以看到上面不加任何选项,被复制之后的某些属性或权限已经被改变了
# 这是个很重要的特性,要注意,文件建立的时间也不一样
# 下面将所有的属性权限都一起复制过来
[root@study tmp]# cp -a /var/log/wtmp wtmp2
[root@study tmp]# ls -l /var/log/wtmp wtmp2
-rw-rw-r--. 1 root utmp 44160 10月 13 14:38 /var/log/wtmp
-rw-rw-r--. 1 root utmp 44160 10月 13 14:38 wtmp2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
上面示例中,不加任何选项会使用预设的配置,比如常常会复制别人的数据(当然需要有 read 权限), 总是希望复制到的数据最后是我们自己的,所以上面示例才有由 utmp 变更为 root
由于具有这个特性,因此在进行备份的时候,需要特别注意的特殊权限文件,例如密码文件(/etc/shadow) 以及一些配置文件,就不能直接以 cp 来复制,需要将全部的属性都原样复制过来
# 复制 etc 目录下的所有内容
[root@study tmp]# cp /etc/ /tmp/
cp: 略过目录"/etc/" # 提示该目录不能直接复制,要加上 -r
[root@study tmp]# cp -r /etc/ /tmp/
# 再次强调,-r 只是能递归复制,但是文件权限等属性还是会更改
# 因此可以使用 cp -a /etc/ /tmp/ 来复制,尤其是在备份的情况下
2
3
4
5
6
# 创建符号链接与实体链接
# 将之前复制过来的 bashrc 建立一个链接档
[root@study tmp]# pwd
/tmp
# 先查看该文件的属性
[root@study tmp]# ls -l bashrc
-rw-r--r--. 1 root root 176 10月 13 15:38 bashrc
# 分别建立 符号链接 和硬式链接
[root@study tmp]# cp -s bashrc bashrc_link
[root@study tmp]# cp -l bashrc bashrc_hlink
[root@study tmp]# ls -l bashrc*
# 注意看这里的数值,源文件是 1 这里变成了 2
-rw-r--r--. 2 root root 176 10月 13 15:38 bashrc
-rw-r--r--. 2 root root 176 10月 13 15:38 bashrc_hlink
# 下面这条数据,在终端中,bashrc_link 会显示浅蓝色
lrwxrwxrwx. 1 root root 6 10月 13 15:55 bashrc_link -> bashrc
2
3
4
5
6
7
8
9
10
11
12
13
14
15
使用 -l 及 -s 都会建立连接档(link file),那么有什么不同呢?
- bashrc_link:使用 s 创建出来的,是符号链接(symbolic link),简单说是一个快捷方式,会链接到 bashrc 中去。有一个 -> 的符号
- bashrc_hlink:使用 l 创建出来的,是实体链接(hard link)
实体链接与源文件的属性与权限一模一样,与尚未链接前的差异是 第二栏 的 link 由 1 变成了 2. 由于实体链接与 i-node 有关,这里先不深入了。后续文件系统部分再深入讲解
# 备份常见下的复制
当源文件比目标新的时候才复制
# 先查看两个文件的时间,可以看到源文件是 2013 年,比目标文件旧
[root@study tmp]# ls -l ~/.bashrc /tmp/bashrc
-rw-r--r--. 1 root root 176 12月 29 2013 /root/.bashrc
-rw-r--r--. 2 root root 176 10月 13 15:38 /tmp/bashrc
# 这里使用 -u 复制后,没有任何提示
[root@study tmp]# cp -u ~/.bashrc /tmp/bashrc
# 再次查看,发现没有复制成功,当前时间是 16:14 了,如果成功,目标文件的时间也会变更
[root@study tmp]# ls -l ~/.bashrc /tmp/bashrc
-rw-r--r--. 1 root root 176 12月 29 2013 /root/.bashrc
-rw-r--r--. 2 root root 176 10月 13 15:38 /tmp/bashrc
2
3
4
5
6
7
8
9
10
# 连接文档的复制
# 该文件是一个符号链接文件
[root@study tmp]# ls -l bashrc_link
lrwxrwxrwx. 1 root root 6 10月 13 15:55 bashrc_link -> bashrc
# 这里使用不加参数复制和加参数复制
[root@study tmp]# cp bashrc_link bashrc_link_1
[root@study tmp]# cp -d bashrc_link bashrc_link_2
[root@study tmp]# ls -l bashrc bashrc_link*
-rw-r--r--. 2 root root 176 10月 13 15:38 bashrc
lrwxrwxrwx. 1 root root 6 10月 13 15:55 bashrc_link -> bashrc
# 可以看到,不加参数复制把源文件复制过来了
-rw-r--r--. 1 root root 176 10月 13 16:16 bashrc_link_1
# 添加 -d 参数,只复制了链接文件本身
lrwxrwxrwx. 1 root root 6 10月 13 16:16 bashrc_link_2 -> bashrc
2
3
4
5
6
7
8
9
10
11
12
13
# 多个文件同时复制到通一个目录下
cp ~/.bashrc ~/.bash_history /tmp/
# 身份不同执行 cp 指令表现不同
# 使用 mrcode 身份, -a 把文件原原本本的复制过来
[mrcode@study ~]$ cp -a /var/log/wtmp /tmp/mrcode_wtmp
[mrcode@study ~]$ ls -l /var/log/wtmp /tmp/mrcode_wtmp
-rw-rw-r--. 1 mrcode mrcode 44160 Oct 13 14:38 /tmp/mrcode_wtmp
-rw-rw-r--. 1 root utmp 44160 Oct 13 14:38 /var/log/wtmp
2
3
4
5
胡发现其他的都一样,但是拥有者和组没有复制过来,这是因为 mrcode 身份无法进行的动作
# 小节
由于 cp 有种种的文件属性与权限的特性,所以在复制时,比必须要清楚的了解到
- 是否需要完整的保留来源文件的信息?
- 来源文件是否为连接档(symbolic link file)?
- 来源档是否为特殊的文件,例如 FIFO、socket 等
- 来源文件是否为目录?
# rm 语出文件或目录
rm [-fir] 文件或目录
- f:force 强制的意思,忽略不存在的文件,不会出现警告信息
- i:互动模式,在闪出去会询问使用者是否操作
- r:递归删除
实践练习
# 互动模式删除
[root@study ~]# cd /tmp/
[root@study tmp]# rm -i bashrc
rm:是否删除普通文件 "bashrc"?y
# 删除的文件名还可以使用通配符, * 表示 0 个或多个
[root@study tmp]# rm -i bashrc*
rm:是否删除普通文件 "bashrc_hlink"?y
rm:是否删除符号链接 "bashrc_link"?y
rm:是否删除普通文件 "bashrc_link_1"?y
rm:是否删除符号链接 "bashrc_link_2"?y
# 删除一个目录, rmdir 无法删除非空目录
[root@study tmp]# rmdir /tmp/etc/
rmdir: 删除 "/tmp/etc/" 失败: 目录非空
# 这里使用 r 参数递归删除
[root@study tmp]# rm -r /tmp/etc/
# 但是出现了交互模式,是因为 root 身份预设加入了参数 -i
rm:是否进入目录"/tmp/etc/"? y
rm:是否删除普通文件 "/tmp/etc/fstab"?y
rm:是否删除普通空文件 "/tmp/etc/crypttab"?y
rm:是否删除符号链接 "/tmp/etc/mtab"?y
rm:是否删除普通文件 "/tmp/etc/resolv.conf"?y
rm:是否进入目录"/tmp/etc/fonts"? ^C
# 在指令前添加反斜杠,可以忽略掉 alias 的指定选项,至于 alias 后续再 bash 章节详讲
\rm -r /tmp/etc/
# 删除一个带有 - 开头的文件
# 先使用 touch 建立一个空文件
touch ./-aaa
# 注意:在 /tmp 下文件太多,常见好的文件就在最前面
ls -l
# 看到文件大小是 0 ,这是一个空文件
-rw-r--r--. 1 root root 0 10月 13 19:05 -aaa-
# 删除刚才创建的,肯定不会成功的,之前讲解过 - 是个特殊字符,表示选项
[root@study tmp]# rm -aaa-
rm:无效选项 -- a
Try 'rm ./-aaa-' to remove the file "-aaa-". # 但是这里给出了建议,添加双引号删除
Try 'rm --help' for more information.
[root@study tmp]# rm "./-aaa-"
rm:是否删除普通空文件 "./-aaa-"?y
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
由于 root 的是天神,所以大部分 distribution 都默认添加了 -i 的选项,删除前请三思啊
# mv 移动文件与目录或更名
mv [-fiu] source destination
mv [options] source1 source2 ... directory
2
- f:强制,如果目标文件已经存在,不会询问,直接覆盖
- i:若目标文件已经存在时,就会询问是否覆盖
- u:若目标已经存在,且 source 比较新,才会功更新该文件
实践练习
[root@study tmp]# cd /tmp/
[root@study tmp]# cp ~/.bashrc bashrc
# 创建目录
[root@study tmp]# mkdir mvtest
# 将刚刚拷贝的 bashrc 复制到目录中
[root@study tmp]# mv bashrc mvtest/
# 目录更名
# 其实还有一个指令 rename,该指令专职进行多个文档名同时更名,并非针对单一文件更名
# 与 mv 不同,详细请 man rename
[root@study tmp]# mv mvtest/ mvtest2
2
3
4
5
6
7
8
9
10
11
# 取得路径的文件名与目录名称,basename、dirname
每个文件的完整文档名包含了前面的目录与最终的文件名,而每个文档名的长度都可达 255 个字符, 那么怎么区分哪个是文件名?哪个是目录名?可以使用斜线「/」来分辨
一般要获取文件名或目录名称,都是些程序的手来判断用,所以这部分指令可以用在后续的 shell scripts 里面。
# /etc/sysconfig/network 比如这个路径
# 可以使用指令分别获取到他的目录与文件名
[root@study tmp]# basename /etc/sysconfig/network
network
[root@study tmp]# dirname /etc/sysconfig/network
/etc/sysconfig
2
3
4
5
6
7