根文件系统与子文件系统

根文件系统(root filesystem)

根文件系统是整个文件系统的基础,不能“脱卸(umount)”

子文件系统

  • 子文件系统,包括硬盘,软盘,CD-ROM,USB盘,网络文件系统NFS
  • 以根文件系统中某一子目录的身份出现(不似Windows逻辑盘)

独立的存储结构

根文件系统和子文件系统都有其自己独立的文件系统存储结构,甚至文件系统的格式也不同

mkfs和mount:文件系统的创建和安装

创建文件系统

1
mkfs /dev/sdb

块设备文件/dev/sdb上创建文件系统(make filesystem)

安装子文件系统mount

1
mount /dev/sdb /mnt

/mnt可以是任一个事先建好的空目录名,允许处于根文件系统的任何目录中,此后,操作子目录/mnt就是对子文件系统的访问。对于应用程序来说,从所操作的文件或目录名,看不出和其它根文件系统的对象有什么区别。

不带参数的mount命令

列出当前已安装的所有的子文件系统

1
2
3
4
5
6
7
8
9
root@localhost ~]# mount
/dev/block/mmcblk0p53 on / type ext4 (rw,seclabel,relatime,discard,noauto_da_alloc,errors=panic,data=ordered)
proc on /proc type proc (rw,relatime)
sys on /sys type sysfs (rw,seclabel,relatime)
tmpfs on /dev type tmpfs (rw,seclabel,nosuid,relatime,size=1822552k,nr_inodes=455638,mode=755)
tmpfs on /dev/shm type tmpfs (rw,seclabel,nosuid,nodev,relatime)
devpts on /dev/pts type devpts (rw,seclabel,relatime,mode=600)
/data/media on /mnt/files type sdcardfs (rw,nosuid,nodev,relatime,uid=1023,gid=1023,derive=legacy,reserved=50MB)
[root@localhost ~]#

umount:文件系统的卸载

umount命令

功能与mount命令相反,卸载一个已安装的子文件系统。例如:

1
umount /dev/sdb

df: 文件系统空闲空间

1
2
3
4
5
6
7
[root@localhost ~]# df
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/block/bootdevice/by-name/userdata 56814352 24486508 32311460 44% /
tmpfs 1822552 368 1822184 1% /dev
tmpfs 1843032 0 1843032 0% /dev/shm
/data/media 56763152 24502892 32260260 44% /mnt/files
[root@localhost ~]#
1
2
3
4
5
6
7
[root@localhost ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/block/bootdevice/by-name/userdata 55G 24G 31G 44% /
tmpfs 1.8G 368K 1.8G 1% /dev
tmpfs 1.8G 0 1.8G 0% /dev/shm
/data/media 55G 24G 31G 44% /mnt/files
[root@localhost ~]#

命令行参数的三种风格

类似dd命令的风格

特点:命令行参数采用param=value的风格

1
dd if=sysdisk.img of=/dev/sdb

用dd命令将硬盘映像拷贝到硬盘:

  • if指定输入文件,
  • of指定输出文件
dd if=/dev/urandom of=test.dat bs=1024 count=512

用dd命令,生成512KB测试数据文件test.dat。
命令行参数中:if,of,bs,count分别指定输入文件,输出文件,块大小(block size),以及块计数.

类似find和gcc的风格

特点:以减号打头的一个由多个字符构成的单词用作选项

find src -name '*.c' -type f -exec dos2unix --keepdate {} \;

将所有扩展名.c的普通文件由Windows文本格式转为Linux格式

1
gcc -O0 -Wall -g -masm=intel -Wa,-ahl -c shudu.c

编译C语言源程序文件mytest.c并生成C程序与汇编代码对比的列表信息

类似ls和grep的风格:现今流行的格式

特点:长选项与短选项,有的选项同时有两种格式,也有的选项仅有长格式或仅有短格式
例如:ls(其中-w选项指定一个整数参数值告知ls排版时屏幕的列宽度)

ls长选项

1
ls --classify --all --size --human-readable --width=80 /home/jiang

ls短选项

ls多个选项挤在一起:

1
ls -Fashw80 /home/jiang

多个选项分开:

1
ls -F -a -s -h -w 80 /home/jiang

还可以把选项放到后面,这种情况便于在上一个命令后面追加选项:

1
ls -F -w80 /home/jiang -has

用独立的命令行参数--显式地标识选项结束

选项的处理统一由C语言标准动态链接库libc.so中库函数getopt_long()完成

我们在设置命令的选项的时候,尽量使用类似ls这种的具有长短选项的风格。

示例

1
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
LS(1)                                                                 User Commands                                                                LS(1)

NAME
ls - list directory contents

SYNOPSIS
ls [OPTION]... [FILE]...

DESCRIPTION
List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

Mandatory arguments to long options are mandatory for short options too.

-a, --all
do not ignore entries starting with .

-A, --almost-all
do not list implied . and ..

--author
with -l, print the author of each file

-b, --escape
print C-style escapes for nongraphic characters

--block-size=SIZE
scale sizes by SIZE before printing them; e.g., '--block-size=M' prints sizes in units of 1,048,576 bytes; see SIZE format below

-B, --ignore-backups
do not list implied entries ending with ~

-c with -lt: sort by, and show, ctime (time of last modification of file status information); with -l: show ctime and sort by name; other‐
wise: sort by ctime, newest first

-C list entries by columns

--color[=WHEN]
colorize the output; WHEN can be 'never', 'auto', or 'always' (the default); more info below

-d, --directory
list directories themselves, not their contents

-D, --dired
generate output designed for Emacs' dired mode

-f do not sort, enable -aU, disable -ls --color

-F, --classify
append indicator (one of */=>@|) to entries

--file-type
likewise, except do not append '*'

--format=WORD
across -x, commas -m, horizontal -x, long -l, single-column -1, verbose -l, vertical -C

--full-time
like -l --time-style=full-iso

-g like -l, but do not list owner

--group-directories-first
group directories before files;

can be augmented with a --sort option, but any use of --sort=none (-U) disables grouping

-G, --no-group
in a long listing, don't print group names

-h, --human-readable
with -l, print sizes in human readable format (e.g., 1K 234M 2G)

--si likewise, but use powers of 1000 not 1024

-H, --dereference-command-line
follow symbolic links listed on the command line

--dereference-command-line-symlink-to-dir
follow each command line symbolic link

that points to a directory

--hide=PATTERN
do not list implied entries matching shell PATTERN (overridden by -a or -A)

--indicator-style=WORD
append indicator with style WORD to entry names: none (default), slash (-p), file-type (--file-type), classify (-F)

-i, --inode
print the index number of each file

-I, --ignore=PATTERN
do not list implied entries matching shell PATTERN

-k, --kibibytes
default to 1024-byte blocks for disk usage

-l use a long listing format

-L, --dereference
when showing file information for a symbolic link, show information for the file the link references rather than for the link itself

-m fill width with a comma separated list of entries

-n, --numeric-uid-gid
like -l, but list numeric user and group IDs

-N, --literal
print raw entry names (don't treat e.g. control characters specially)

-o like -l, but do not list group information

-p, --indicator-style=slash
append / indicator to directories

-q, --hide-control-chars
print ? instead of nongraphic characters

--show-control-chars
show nongraphic characters as-is (the default, unless program is 'ls' and output is a terminal)

-Q, --quote-name
enclose entry names in double quotes

--quoting-style=WORD
use quoting style WORD for entry names: literal, locale, shell, shell-always, c, escape

-r, --reverse
reverse order while sorting

-R, --recursive
list subdirectories recursively

-s, --size
print the allocated size of each file, in blocks

-S sort by file size

--sort=WORD
sort by WORD instead of name: none (-U), size (-S), time (-t), version (-v), extension (-X)

--time=WORD
with -l, show time as WORD instead of default modification time: atime or access or use (-u) ctime or status (-c); also use specified time
as sort key if --sort=time

--time-style=STYLE
with -l, show times using style STYLE: full-iso, long-iso, iso, locale, or +FORMAT; FORMAT is interpreted like in 'date'; if FORMAT is
FORMAT1<newline>FORMAT2, then FORMAT1 applies to non-recent files and FORMAT2 to recent files; if STYLE is prefixed with 'posix-', STYLE
takes effect only outside the POSIX locale

-t sort by modification time, newest first

-T, --tabsize=COLS
assume tab stops at each COLS instead of 8

-u with -lt: sort by, and show, access time; with -l: show access time and sort by name; otherwise: sort by access time

-U do not sort; list entries in directory order

-v natural sort of (version) numbers within text

-w, --width=COLS
assume screen width instead of current value

-x list entries by lines instead of by columns

-X sort alphabetically by entry extension

-1 list one file per line

SELinux options:

--lcontext
Display security context. Enable -l. Lines will probably be too wide for most displays.

-Z, --context
Display security context so it fits on most displays. Displays only mode, user, group, security context and file name.

--scontext
Display only security context and file name.

--help display this help and exit

--version
output version information and exit

SIZE is an integer and optional unit (example: 10M is 10*1024*1024). Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of
1000).

Using color to distinguish file types is disabled both by default and with --color=never. With --color=auto, ls emits color codes only when
standard output is connected to a terminal. The LS_COLORS environment variable can change the settings. Use the dircolors command to set it.

Exit status:
0 if OK,

1 if minor problems (e.g., cannot access subdirectory),

2 if serious trouble (e.g., cannot access command-line argument).

GNU coreutils online help: <http://www.gnu.org/software/coreutils/> Report ls translation bugs to <http://translationproject.org/team/>

AUTHOR
Written by Richard M. Stallman and David MacKenzie.

COPYRIGHT
Copyright © 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

SEE ALSO
The full documentation for ls is maintained as a Texinfo manual. If the info and ls programs are properly installed at your site, the command

info coreutils 'ls invocation'

should give you access to the complete manual.

GNU coreutils 8.22 November 2020 LS(1)

Linux系统命令和用户程序(ap)运行时获取信息的方式

Linux系统命令和用户程序(ap)

  • 从操作系统看,在地位上相同,都属于用户态程序
  • 运行时需要获取的信息包括配置信息、处理方式(选项参数)、被处理的对象

配置信息等硬编码是不可取的

  • 硬编码需要编程时就确定服务器的地址,
  • 程序运行时就无法改变,太不灵活

运行时获取信息的常见方式

易变性从小到大为

  1. 配置文件
  2. 环境变量
  3. 命令行参数
  4. 交互式键盘输入

运行时获取信息的方式

配置文件

  • 一般较复杂的程序会提供配置文件以存储配置信息或者偏好配置信息
  • 分为系统级偏好设置用户级偏好设置,例如bash的/etc/profile~/.bash_profile
  • 配置文件提供了灵活性(同一个程序文件因用户不同读取的配置文件不同而表现不同),变更这些信息不很方便,一般而言,存入配置文件的是那些不需要变化的配置信息或选项信息

环境变量

命令env可以打印出当前的环境变量。

  • 一般是些与“环境”相关的配置或选项信息,信息量不大。这些选择在一段时间内反复使用同一个命令或者不同命令时保持不变。例如:LANG(语言选择),HOME(主目录),TERM(终端类型),PATH(可执行文件的查找路径),CLASSPATH(类库查找路径),CVSROOT
  • 虽然运行的程序(可执行文件)是完全相同的一个文件,程序通过获得环境变量感知环境的不同,控制自己的行为。
  • 环境变量值的获取与设置:C语言有库函数getenv(),用户设置环境变量的方法也很简单
  • 性能问题:比读取配置文件需要的系统开支要小

使用环境变量示例

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <stdlib.h>
#define DEFAULT_SERVER "180.249.151.131"
int main(void)
{
char *server;
server = getenv("SERVER");
if (server == NULL)
server = DEFAULT_SERVER;
printf("Server [%s]\n", server);
}

运行效果:

1
2
3
4
5
6
[root@localhost Linux命令风格;文件系统]# gcc useEnv.c -o useEnv
[root@localhost Linux命令风格;文件系统]# ls
useEnv useEnv.c
[root@localhost Linux命令风格;文件系统]# ./useEnv
Server [180.249.151.131]
[root@localhost Linux命令风格;文件系统]#

执行命令的时候指定环境变量

直接在命令的前面写上环境变量,然后用空格隔开,然后在输入命令。
格式:

1
环境变量=变量值 命令

例如:

1
2
3
[root@localhost Linux命令风格;文件系统]# SERVER=1.1.1.1 ./useEnv
Server [1.1.1.1]
[root@localhost Linux命令风格;文件系统]#

这种方式只会对当前输入的命令有效:

1
2
3
4
5
[root@localhost Linux命令风格;文件系统]# SERVER=1.1.1.1 ./useEnv
Server [1.1.1.1]
[root@localhost Linux命令风格;文件系统]# ./useEnv
Server [180.249.151.131]
[root@localhost Linux命令风格;文件系统]#

在当前终端中指定环境变量

也可以使用export命令来导出环境变量,这个命令会在当前终端一直有效:

1
2
3
4
5
6
7
8
[root@localhost Linux命令风格;文件系统]# export SERVER=1.2.3.4
[root@localhost Linux命令风格;文件系统]# ./useEnv
Server [1.2.3.4]
[root@localhost Linux命令风格;文件系统]# ./useEnv
Server [1.2.3.4]
[root@localhost Linux命令风格;文件系统]# env |grep 'SERVER'
SERVER=1.2.3.4
[root@localhost Linux命令风格;文件系统]#

运行时获取信息的方式

命令行参数

  • 程序启动之前指定:通过命令行参数,操作员输入命令时提供处理选项和操作对象
  • 每个命令都不同,命令运行完之后,对后续命令无影响
  • 命令行参数的三种风格

    交互式键盘输入:这种方式在Linux命令中极少使用

    程序启动之后通过计算机与操作员之间的人机交互获取信息,C语言scanf(),fgets()函数

这种方式不利于使用管道符和其他的命令结合使用。

tar:文件归档

功能

tar命令最早为顺序访问的磁带机设备而设计的(Tape ARchive,磁带归档),用于保留和恢复磁带上的文件

命令语法

1
tar ctxv[f device]] file-list

功能字母

选项第一字母指定要执行的操作,是必需的
常用的功能字幕如下表所示

tar第一个功能字母 描述
c Create创建新磁带。从头开始写,以前存于磁带上的数据会被覆盖掉
t Table列表。磁带上的文件名列表,当不指定文件名时,将列出所有的文件
x eXtract抽取。从磁带中抽取指定的文件。当不指定文件名时,抽取所有文件

非功能字母

除功能字母外的其它选项

tar非功能字母 描述
v Verbose冗长。每处理一个文件,就打印出文件的文件名,并在该名前冠
以功能字母
f File 。指定设备文件名
z 采用压缩格式(gzip算法)
j 采用压缩格式(bzip2算法)

tar的使用:磁带机操作

1
tar cvf /dev/rct0 .

将当前目录树备份到设备/dev/rct0中,圆点目录是当前目录

1
tar tvf /dev/rct0

查看磁带设备/dev/rct0上的文件目录

1
tar xvf /dev/rct0

将磁带设备/dev/rct0上的文件恢复到文件系统中

tar的使用:文件打包

1
tar cvf my.tar *.[ch] makefile

指定普通文件代替设备文件,将多个文件或目录树存储成一个文件。这是UNIX世界早期最常用的文件和目录打包工具
这一命令危险的误操作是:

1
tar cvf *.[ch] makefile

漏掉了功能字母f必需的“设备文件名”,按照shell对文件名的展开规则,会覆盖掉现存的排位第一的文件
例如shell会把星号替换成如下命令:

1
tar cvf a1.c a2.c ab.h makefile

tar的使用:目录打包

设work是一个有多个层次的子目录

打包目录为.tar

1
tar cvf work.tar work

打包目录为.tar.gz

1
tar cvzf work.tar.gz work

他报目录为.tar.bz2

1
tar cvjf work.tar.bz2 work

查看.tar文件中的文件目录

查看归档文件中的文件目录:

1
tar tvf work.tar.gz   

解压.tar文件

从归档文件中恢复目录树:

1
tar xvf work.tar.gz

注意:文件名后缀.tar,.tar.gz,.tar.bz2仅仅是惯例,不是系统级强制要求

文件压缩和解压缩相关命令

gzip/gunzip (执行速度快)
bzip2/bunzip2 (占用较多的CPU时间)

问题

遍历当前目录.的所有后缀为.c文件,查找文件中带有–help的内容:

1
find . -name \*.c -exec grep -n -- --help {} /dev/null \;

借助find的“壳”功能去遍历目录,对遍历到的每个符合条件的文件执行grep命令。

缺点:效率低,因为每个命中的对象都需要执行grep命令:
对于find命令查找到的文件,创建一个grep进程来处理这个文件,完成任务后grep进程消亡;
然后find命令找到下一个文件,再创建一个grep进程来处理。

也就是说对于find找到n个文件,就需要创建n个grep进程来处理这n个文件。

示例

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost 批量处理文件]# tree -N
.
├── a
│   └── HelloWorld.c
├── b
│   └── WorldHello.c
├── hello.c
├── other.txt
└── world.c

2 directories, 5 files
[root@localhost 批量处理文件]#

各文件内容

1
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
[root@localhost 批量处理文件]# cat hello.c 
a
b
c
d
--help
-hello
--hello
[root@localhost 批量处理文件]# cat world.c
1
2
3
-world
--help
--world
[root@localhost 批量处理文件]# cat a/HelloWorld.c
a
1
b
2
helloworld
-helloworld
--helloworld
helloworld8
[root@localhost 批量处理文件]# cat b/WorldHello.c
1
a
2
b
WorldHello
--help
--worldhello
[root@localhost 批量处理文件]# cat other.txt
非.c文件
xxx
yyy
zzz
--help
[root@localhost 批量处理文件]#

在当前目录下的所有.c文件中查找–help字符串:

1
2
3
4
5
[root@localhost 批量处理文件]# find . -name \*.c -exec grep -n -- --help {} /dev/null \;
./hello.c:5:--help
./world.c:5:--help
./b/WorldHello.c:6:--help
[root@localhost 批量处理文件]#

grep -nr – –help *.c

grep -r

grep命令也提供了-r选项,可以递归地搜索子目录下的文件,

但是对于如下命令:

1
grep -nr -- --help *.c 

达不到效果,因为这里的子目录的名字为a/b/,这些子目录的名字不能被*.c匹配。

1
2
3
4
[root@localhost 批量处理文件]# grep -nr -- --help *.c 
hello.c:5:--help
world.c:5:--help
[root@localhost 批量处理文件]#

而命令:

1
grep -nr -- --help *

倒是可以检索出文件中带--help的内容,但是这样是检索所有的文件,不是单独的检索.c文件,输出结果会被无用的信息干扰,甚至淹没。

1
2
3
4
5
6
[root@localhost 批量处理文件]# grep -nr -- --help *
b/WorldHello.c:6:--help
hello.c:5:--help
other.txt:5:--help
world.c:5:--help
[root@localhost 批量处理文件]#

所以还是应该使用find精确筛选的功能。然后再通过grep搜索这些文件的内容。

利用find与xargs的组合

对于上述命令:

1
find . -name \*.c -exec grep -n -- --help {} /dev/null \;

如果能把

1
find . -name \*.c -print

的输出结果,也就是生成的文件名列表追加在下列grep命令后面就可以好了。

1
grep -n -- --help filelist

这样我们就只需要执行一次grep命令,处理这些文件列表即可。不需要对一个文件,的执行一次grep命令。

命令xargs可以用来完成这个工作:

1
find . -name \*.c -print | xargs grep -n -- --help

xargs命令把标准输入追加到它的参数列表后面,也就是上述grep -n -- --help的后面,再作为一个命令来执行。这样利用find精确筛选,利用grep批量处理文件,提高效率。

1
2
3
4
5
[root@localhost 批量处理文件]# find . -name \*.c -print | xargs grep -n -- --help
./hello.c:5:--help
./world.c:5:--help
./b/WorldHello.c:6:--help
[root@localhost 批量处理文件]#

验证使用xargs可以节省时间

执行

1
find . -name \*.c -print | xargs grep -n -- --help

需要的时间:

1
2
3
4
5
6
7
8
9
[root@localhost 批量处理文件]# time find . -name \*.c -print | xargs grep -n -- --help
./hello.c:5:--help
./world.c:5:--help
./b/WorldHello.c:6:--help

real 0m0.022s
user 0m0.010s
sys 0m0.000s
[root@localhost 批量处理文件]#

执行

1
find . -name \*.c -exec grep -n -- --help {} /dev/null \;

需要的时间:

1
2
3
4
5
6
7
8
9
[root@localhost 批量处理文件]# time find . -name \*.c -exec grep -n -- --help {} /dev/null \;
./hello.c:5:--help
./world.c:5:--help
./b/WorldHello.c:6:--help

real 0m0.044s
user 0m0.000s
sys 0m0.010s
[root@localhost 批量处理文件]#

可以看到使用xargs确实节省和时间。

xargs:将标准输入组织成命令执行

  • 将标准输入构造为命令的命令行参数
  • 如果标准输入的数据量很大,xargs指定的处理程序会启动多个进程运行,每个进程处理一批。
  • 可以使用xargs的-n选项指定每批处理多少个
  • xargs经常与find配合使用,也可以与其它命令组合使用

xargs:构造参数列表并运行命令

解决shell文件名生成时,因为文件太多,缓冲区空间受限而文件名展开失败的问题

对于命令:

1
rm -f *.dat

如果匹配的文件很多,则文件名*.dat可能会展开失败,
此时可以使用下面的命令

1
ls | grep ".dat$" | xargs rm -f

find命中目录名因删除目录导致目录遍历过程遇到麻烦

1
find . -name CVS -exec rm -rf {} \;

改为:

1
find . -name CVS -print | xargs rm -rf

Linux 目录遍历命令find的应用

查找当前目录下的所有目录

从当前目录开始查找,寻找所有目录,打印路径名:

1
find . -type d -print

结果:按层次列出当前的目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld.c
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
├── p1.c
└── p2.c

3 directories, 6 files
[root@localhost 文件管理和目录管理]# find . -type d -print
.
./hello
./hello/world
./文件管理
[root@localhost 文件管理和目录管理]#

指定了两个条件:名字与stud*匹配,类型为目录

1
find . -name 'stud*' -type d -print

使用多个条件选项

两个条件逻辑“与”,必须同时符合这两个条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld.c
├── hello2
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   ├── p1.c
│   └── p2.c
└── ht.c

3 directories, 6 files
[root@localhost 文件管理和目录管理]# find . -name 'hello*' -type d -print
./hello
./hello2
[root@localhost 文件管理和目录管理]#

检索最近10天内修改过的普通文件

从根目录开始检索最近10天之内曾经修改过的普通磁盘文件(目录不算)

1
find / -type f -mtime -10 -print

当前的时间:

1
2
3
[root@localhost 文件管理和目录管理]# date
2021年 06月 09日 星期三 13:29:26 CST
[root@localhost 文件管理和目录管理]#

当前目录树结构,以及各个文件的最后修改时间:

1
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
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── HelloWorld.c
├── hello2
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   ├── p1.c
│   └── p2.c
└── ht.c

2 directories, 6 files
[root@localhost 文件管理和目录管理]# ls -l *
-rw-r--r--. 1 root root 34 6月 3 17:33 ht.c

hello:
总用量 0
-rw-r--r--. 1 root root 0 6月 7 16:49 HelloWorld.c

hello2:
总用量 16
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld2.c
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld.c
-rw-r--r--. 1 root root 66 6月 2 17:00 p1.c
-rw-r--r--. 1 root root 66 6月 2 17:16 p2.c
[root@localhost 文件管理和目录管理]#

查找刚好5天之前更新的文件:

1
2
3
[root@localhost 文件管理和目录管理]# find . -type f -mtime 5 -print
./ht.c
[root@localhost 文件管理和目录管理]#

查找刚好6天之前更新的文件:

1
2
3
4
5
6
[root@localhost 文件管理和目录管理]# find . -type f -mtime 6 -print
./hello2/HelloWorld2.c
./hello2/HelloWorld.c
./hello2/p1.c
./hello2/p2.c
[root@localhost 文件管理和目录管理]#

查找5天之前更新的文件

1
2
3
4
5
6
7
[root@localhost 文件管理和目录管理]# find . -type f -mtime +4 -print
./hello2/HelloWorld2.c
./hello2/HelloWorld.c
./hello2/p1.c
./hello2/p2.c
./ht.c
[root@localhost 文件管理和目录管理]#

使用逻辑运算符非!

1
find . ! -type d -links +2 -print

从当前目录开始检索link数大于2的非目录文件
条件“非”用!
注意:!号与-type之间必须保留一空格

1
2
3
4
5
6
7
8
9
[root@localhost 文件管理和目录管理]# find . -type f -mtime 6 -print
./hello2/HelloWorld2.c
./hello2/HelloWorld.c
./hello2/p1.c
./hello2/p2.c
[root@localhost 文件管理和目录管理]# find . -type f ! -mtime 6 -print
./hello/HelloWorld.c
./ht.c
[root@localhost 文件管理和目录管理]#

使用逻辑运算或-o

寻找当前目录下大于100字节的名叫hello的或.c后缀的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost 文件管理和目录管理]# tree -Nh
.
├── [ 131] arg.c
├── [4.0K] hello
│   └── [ 0] HelloWorld.c
├── [4.0K] hello2
│   ├── [ 66] HelloWorld2.c
│   ├── [ 66] HelloWorld.c
│   ├── [ 66] p1.c
│   └── [ 66] p2.c
├── [ 121] helloworld.c
└── [ 34] ht.c

2 directories, 8 files
[root@localhost 文件管理和目录管理]# find -size +100c \( -name 'hello' -o -name '*.c' \) -print
./hello
./arg.c
./helloworld.c
[root@localhost 文件管理和目录管理]#
  • 使用了两条件“或” (-o)及组合(圆括号)
  • 不要遗漏了所必需的引号,反斜线和空格,尤其是圆括号前和圆括号后。圆括号是shell的特殊字符,所以需要写成\(\)

其他写法

1
2
3
4
5
[root@localhost 文件管理和目录管理]# find -size +100c '(' -name 'hello' -o -name '*.c' ')' -print
./hello
./arg.c
./helloworld.c
[root@localhost 文件管理和目录管理]#
1
2
3
4
5
[root@localhost 文件管理和目录管理]# find -size +100c \( -name 'hello' -o -name '*.c' ')' -print
./hello
./arg.c
./helloworld.c
[root@localhost 文件管理和目录管理]#

find -exec执行命令

1
find . -type d -print -exec ls -l {} \;
  • -exec及随后的分号;之间的内容作为一条命令执行
  • shell中分号;有特殊含义,前面加反斜线\
  • {}代表遍历时所查到的符合条件的路径名。注意,两花括号间无空格,之后的空格不可省略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost 文件管理和目录管理]# tree -N
.
├── arg.c
├── hello
│   └── HelloWorld.c
├── hello2
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   ├── p1.c
│   └── p2.c
├── helloworld.c
└── ht.c

2 directories, 8 files
[root@localhost 文件管理和目录管理]#

查找当前目录下的子目录,并对这些子目录执行ls -l命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost 文件管理和目录管理]# find . -type d -print -exec ls -l {} \;
.
总用量 20
-rw-r--r--. 1 root root 131 6月 9 14:12 arg.c
drwxr-xr-x. 2 root root 4096 6月 9 13:28 hello
drwxr-xr-x. 2 root root 4096 6月 8 01:23 hello2
-rw-r--r--. 1 root root 121 6月 9 14:13 helloworld.c
-rw-r--r--. 1 root root 34 6月 3 17:33 ht.c
./hello
总用量 0
-rw-r--r--. 1 root root 0 6月 7 16:49 HelloWorld.c
./hello2
总用量 16
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld2.c
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld.c
-rw-r--r--. 1 root root 66 6月 2 17:00 p1.c
-rw-r--r--. 1 root root 66 6月 2 17:16 p2.c
[root@localhost 文件管理和目录管理]#

查找当前目录下的子目录,不包括这个.目录,并对这些子目录执行ls -l命令。

1
2
3
4
5
6
7
8
9
10
11
[root@localhost 文件管理和目录管理]# find . -type d ! -name '.'  -print -exec ls -l {} \;
./hello
总用量 0
-rw-r--r--. 1 root root 0 6月 7 16:49 HelloWorld.c
./hello2
总用量 16
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld2.c
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld.c
-rw-r--r--. 1 root root 66 6月 2 17:00 p1.c
-rw-r--r--. 1 root root 66 6月 2 17:16 p2.c
[root@localhost 文件管理和目录管理]#

find -ok执行命令

-ok选项在执行指定的命令前等待用户确认

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost 文件管理和目录管理]# find . -type d -print -ok ls -l {} \;
.
< ls ... . > ? n
./hello
< ls ... ./hello > ? y
总用量 0
-rw-r--r--. 1 root root 0 6月 7 16:49 HelloWorld.c
./hello2
< ls ... ./hello2 > ? y
总用量 16
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld2.c
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld.c
-rw-r--r--. 1 root root 66 6月 2 17:00 p1.c
-rw-r--r--. 1 root root 66 6月 2 17:16 p2.c
[root@localhost 文件管理和目录管理]#

利用find的递归式遍历目录的功能在文件中搜寻字符串

1
find src -name \*.c -exec grep -n -- --help {} /dev/null \;

在目录src中所有.c文件中查找–help字符串
grep的-n选项,–选项,/dev/null文件的作用
其他类似做法:将满足条件的文件转码或者对文件进行其他分析处理等

运行效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@localhost 文件管理和目录管理]# tree -N
.
├── arg.c
├── hello
│   └── HelloWorld.c
├── hello2
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   ├── p1.c
│   └── p2.c
├── helloworld.c
└── ht.c

2 directories, 8 files
[root@localhost 文件管理和目录管理]# cat ht.c
56
-1
-4
8
--help
--hello
--world
[root@localhost 文件管理和目录管理]# find . -name \*.c -exec grep -n -- --help {} /dev/null \;
./ht.c:5:--help
[root@localhost 文件管理和目录管理]#

find:遍历目录树

功能

find命令从指定的查找范围开始,递归地查找子目录,凡满足条件的文件或目录,执行规定的动作

举例

1
find verl.d ver2.d -name '*.c' -print

范围:当前目录的子目录ver1.d 和ver2.d
条件:与名字*.c匹配。注:*.c应当用引号括起
动作:把查找到的文件的路径名打印出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld
│   └── HelloWorld.c
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 6 files
[root@localhost 文件管理和目录管理]# find hello/ 文件管理/ -name '*.c' -print
hello/world/HelloWorld/HelloWorld.c
文件管理/HelloWorld2.c
文件管理/HelloWorld.c
文件管理/备份/p1.c
文件管理/备份/p2.c
[root@localhost 文件管理和目录管理]#

find命令的特点

命令的特点

  • 功能强,选项较多
  • 递归式查找,提供了一种遍历目录树的手段
  • find命令提供的灵活性:在“动作”中可以指定任何命令(也包括用户自己编写的处理程序),使得find成为一个任意处理命令可以借用来进行目录遍历的壳(类似awk对文本的逐行扫描,find对目录森林中的文件和目录逐个扫描)

find关于条件的选项

-name wildcard

wildcard表示文件名通配符
文件名wildcard匹配,注意:

  • 必需的引号
    • 这样shell不会对通配符进行替换
  • 这里的“文件名”仅指路径名的最后一部分
  • 对通配符的解释由find完成

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld
│   └── HelloWorld.c
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 6 files
[root@localhost 文件管理和目录管理]# find -name '*World*.c'
./hello/world/HelloWorld/HelloWorld.c
./文件管理/HelloWorld2.c
./文件管理/HelloWorld.c
[root@localhost 文件管理和目录管理]#

-regex pattern

整个路径名与正则表达式pattern匹配

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld
│   └── HelloWorld.c
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 6 files
[root@localhost 文件管理和目录管理]# find -regex '.*[0-9]\.c'
./文件管理/HelloWorld2.c
./文件管理/备份/p1.c
./文件管理/备份/p2.c
[root@localhost 文件管理和目录管理]#

-type 文件类型

这里的文件类型使用一个字母来表示,下标是文件类型字母和对应的文件类型。

find -type的选项 描述
f 普通文件
d 目录
l 符号连接文件
c 字符设备文件
b 块设备文件
p 管道文件

示例

当前目录结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld
│   └── HelloWorld.c
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 6 files
[root@localhost 文件管理和目录管理]#

find找出所有的子目录

遍历当前目录,找出所有的子目录。

1
2
3
4
5
6
7
8
[root@localhost 文件管理和目录管理]# find -type d
.
./hello
./hello/world
./hello/world/HelloWorld
./文件管理
./文件管理/备份
[root@localhost 文件管理和目录管理]#

find找出所有的普通文件:

1
2
3
4
5
6
7
8
[root@localhost 文件管理和目录管理]# find -type f
./hello/world/HelloWorld/HelloWorld.c
./ht.c
./文件管理/HelloWorld2.c
./文件管理/HelloWorld.c
./文件管理/备份/p1.c
./文件管理/备份/p2.c
[root@localhost 文件管理和目录管理]#

-size ±n单位

帮助文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-size n[cwbkMG]
File uses n units of space. The following suffixes can be used:

`b' for 512-byte blocks (this is the default if no suffix is used)

`c' for bytes

`w' for two-byte words

`k' for Kilobytes (units of 1024 bytes)

`M' for Megabytes (units of 1048576 bytes)

`G' for Gigabytes (units of 1073741824 bytes)

The size does not count indirect blocks, but it does count blocks in sparse files that are not actually allocated. Bear in mind that the
`%k' and `%b' format specifiers of -printf handle sparse files differently. The `b' suffix always denotes 512-byte blocks and never 1
Kilobyte blocks, which is different to the behaviour of -ls.

指定文件大小(大于+,等于,小于-)

find -size单位标识符 大小
c 字节
w 双字节
k 千字节
M 兆字节
G 千兆字节

示例

当前目录下各个文件的大小:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost 文件管理和目录管理]# tree -Nh
.
├── [4.0K] hello
│   └── [4.0K] world
│   └── [4.0K] HelloWorld
│   └── [ 0] HelloWorld.c
├── [ 34] ht.c
└── [4.0K] 文件管理
├── [ 66] HelloWorld2.c
├── [ 66] HelloWorld.c
└── [4.0K] 备份
├── [ 66] p1.c
└── [ 66] p2.c

5 directories, 6 files
[root@localhost 文件管理和目录管理]#

查找大小为66个字节的文件:

1
2
3
4
5
6
[root@localhost 文件管理和目录管理]# find -size 66c
./文件管理/HelloWorld2.c
./文件管理/HelloWorld.c
./文件管理/备份/p1.c
./文件管理/备份/p2.c
[root@localhost 文件管理和目录管理]#

使用的单位为w,w是双字节的意思。33w也就是66字节

1
2
3
4
5
6
[root@localhost 文件管理和目录管理]# find -size 33w
./文件管理/HelloWorld2.c
./文件管理/HelloWorld.c
./文件管理/备份/p1.c
./文件管理/备份/p2.c
[root@localhost 文件管理和目录管理]#

查找大小小于66字节的文件

1
2
3
4
[root@localhost 文件管理和目录管理]# find -size -66c
./hello/world/HelloWorld/HelloWorld.c
./ht.c
[root@localhost 文件管理和目录管理]#

查找大于66字节的文件

1
2
3
4
5
6
7
8
[root@localhost 文件管理和目录管理]# find -size +66c
.
./hello
./hello/world
./hello/world/HelloWorld
./文件管理
./文件管理/备份
[root@localhost 文件管理和目录管理]#

-mtime ±ndays

文件最近修改时间

帮助文档

1
2
3
4
5
-mmin n
对文件数据的最近一次修改是在 n 分钟之前。

-mtime n
对文件数据的最近一次修改是在 n*24 小时之前。

示例

1
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
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld
│   └── HelloWorld.c
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 6 files
[root@localhost 文件管理和目录管理]# ls -l
总用量 12
drwxr-xr-x. 3 root root 4096 6月 7 16:17 hello
-rw-r--r--. 1 root root 34 6月 3 17:33 ht.c
drwxr-xr-x. 3 root root 4096 6月 2 17:28 文件管理
[root@localhost 文件管理和目录管理]# ls -l 文件管理/*
-rw-r--r--. 1 root root 66 6月 2 17:17 文件管理/HelloWorld2.c
-rw-r--r--. 1 root root 66 6月 2 17:17 文件管理/HelloWorld.c

文件管理/备份:
总用量 8
-rw-r--r--. 1 root root 66 6月 2 17:00 p1.c
-rw-r--r--. 1 root root 66 6月 2 17:16 p2.c
[root@localhost 文件管理和目录管理]# ls -l hello/world/*
总用量 0
-rw-r--r--. 1 root root 0 6月 7 16:49 HelloWorld.c
[root@localhost 文件管理和目录管理]# date
2021年 06月 07日 星期一 23:46:44 CST
[root@localhost 文件管理和目录管理]#

查找6月3日(4天之前)的文件

1
2
3
4
5
6
7
8
[root@localhost 文件管理和目录管理]# find -mtime 4
./ht.c
[root@localhost 文件管理和目录管理]# ls -l
总用量 12
drwxr-xr-x. 3 root root 4096 6月 7 16:17 hello
-rw-r--r--. 1 root root 34 6月 3 17:33 ht.c
drwxr-xr-x. 3 root root 4096 6月 2 17:28 文件管理
[root@localhost 文件管理和目录管理]#

查找6月2日(5天之前)的文件:

1
2
3
4
5
6
7
8
[root@localhost 文件管理和目录管理]# find -mtime 5
./文件管理
./文件管理/HelloWorld2.c
./文件管理/HelloWorld.c
./文件管理/备份
./文件管理/备份/p1.c
./文件管理/备份/p2.c
[root@localhost 文件管理和目录管理]#

-newer file

文件最近修改时间比file的还晚的文件。
当前文件目录下和子目录下的文件的最后修改时间:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost 文件管理和目录管理]# ls -l *
-rw-r--r--. 1 root root 0 6月 7 16:49 HelloWorld.c
-rw-r--r--. 1 root root 34 6月 3 17:33 ht.c

文件管理:
总用量 16
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld2.c
-rw-r--r--. 1 root root 66 6月 2 17:17 HelloWorld.c
-rw-r--r--. 1 root root 66 6月 2 17:00 p1.c
-rw-r--r--. 1 root root 66 6月 2 17:16 p2.c
[root@localhost 文件管理和目录管理]#

查找比p2.c修改时间晚的文件:

1
2
3
4
5
6
7
8
[root@localhost 文件管理和目录管理]# find -newer 文件管理/p2.c 
.
./HelloWorld.c
./ht.c
./文件管理
./文件管理/HelloWorld2.c
./文件管理/HelloWorld.c
[root@localhost 文件管理和目录管理]#

其它条件选项

(文件属性字段可用来对遍历到的目标进行筛选,查阅find手册)

  • 指定i节点号-inum
  • 可指定文件主-user-nouser
  • 可指定用户组-group-nogroup
  • 指定link数-links
  • 指定路径深度-depth
  • 指定文件的访问权限-perm

复合条件

可以用() –o !等表示多条件的“与”,“或”,“非”

find关于动作的选项

-print

打印查找的文件的路径名

-exec

  • 对查找到的目标执行某一命令
  • -exec及随后的分号之间的内容作为一条命令
    在这命令的命令参数中,{}代表遍历到的目标文件的路径名

-ok

  • -exec类似,只是对查找到符合条件的目标执行一个命令前需要经过操作员确认。

路径名

文件.与..

在目录表中确实有...这两个文件,这两个目录项由系统创建和删除。

1
2
3
[root@localhost 文件管理和目录管理]# ls -a
. .. ht.c 文件管理和目录管理2
[root@localhost 文件管理和目录管理]#

主目录(Home Directory)

  • 每个用户都有自己独立的主目录
  • 用env命令查环境变量HOME的值
1
2
3
4
5
6
[root@localhost 文件管理和目录管理]# env|grep 'HOME'
JRE_HOME=/opt/java/jdk1.8.0_281/jre
JAVA_HOME=/opt/java/jdk1.8.0_281
HOME=/root
CLASSPATH=.:JAVA_HOME/lib:JRE_HOME/lib:
[root@localhost 文件管理和目录管理]#

绝对路径名与相对路径名

linux的路径分量分隔符用斜线/,而不是反斜线
以斜线开头的是绝对路径,例如

1
/home/stud/liu

没有斜线开头的则是从当前目录开始的相对路径:

1
test/case1/conf

当前工作目录

当前工作目录是进程属性的一部分,每进程一个。

打印/改变当前目录

pwd命令:打印当前工作目录

print working directory

cd命令:改变当前工作目录

(Change Directory)

1
cd /usr/include

斜线前必须有空格:

1
cd /
1
cd ..

cd命令无实参,直接输入cd回车:

1
cd
  • 在Windows中,打印当前工作目录
  • 1
    2
    3
    G:\Desktop\test\CMD>cd
    G:\Desktop\test\CMD
    G:\Desktop\test\CMD>
  • 在UNIX中,回到用户的主目录(Home Directory)
  • 1
    2
    [root@localhost 文件管理和目录管理]# cd
    [root@localhost ~]#

注意

cd是shell的一个内部命令

创建/删除目录

创建目录mkdir

例:

1
mkdir sun/work.d

mkdir除创建目录外,系统自动建立文件.与..

选项-p

自动创建路径中不存在的目录。
例如:

1
mkdir database/2019/09/04/log

示例

1
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
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

2 directories, 5 files
[root@localhost 文件管理和目录管理]# mkdir hello/world/HelloWorld
mkdir: 无法创建目录"hello/world/HelloWorld": 没有那个文件或目录
[root@localhost 文件管理和目录管理]# mkdir -p hello/world/HelloWorld
[root@localhost 文件管理和目录管理]# tree -N
.
├── hello
│   └── world
│   └── HelloWorld
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 5 files
[root@localhost 文件管理和目录管理]#

删除目录rmdir

例:

1
rmdir sun/work.d

要求被删除的目录除.与..外无其它文件或目录
其他命令:

1
rm -r sun/work.d

cp: 复制目录

cp命令选项–r,递归地复制一个目录

1
cp -r dir1 dir2

根据dir2是否存在,执行结果有差异:

  • 若dir2不存在,则新建子目录dir2,把dir1下内容拷入dir2下
  • 若dir2已存在,则dir2下新建子目录dir1,把dir1下内容拷入dir2/dir1下

cp -r目标目录不存在的情况

1
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
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

2 directories, 5 files
[root@localhost 文件管理和目录管理]# cp -r 文件管理/ 文件管理2
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理2
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

4 directories, 9 files
[root@localhost 文件管理和目录管理]#

cp -r目标目录已存在的情况

1
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
[root@localhost 文件管理和目录管理]# rm -rf 文件管理2/
[root@localhost 文件管理和目录管理]# mkdir 文件管理3
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3

3 directories, 5 files
[root@localhost 文件管理和目录管理]# cp -r 文件管理/ 文件管理3
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 9 files
[root@localhost 文件管理和目录管理]#

cp –v:冗长(verbose)方式

复制目录时实时列出正在复制的文件的名字

cp -u: 增量拷贝

选项–u,增量拷贝(update),便于备份目录

  • 根据文件的时戳,不拷贝相同的或者过时的版本的文件,以提高速度
  • dir1和dir2不慎颠倒位置,不会出现灾难性后果
  • Windows中类似功能的命令XCOPY,选项/D可以用来实现增量拷贝(Date)

示例

当前目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 9 files
[root@localhost 文件管理和目录管理]#

删除子目录文件管理3上的部分目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost 文件管理和目录管理]# rm -rf 文件管理3/文件管理/备份/
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3
└── 文件管理
├── HelloWorld2.c
└── HelloWorld.c

4 directories, 7 files
[root@localhost 文件管理和目录管理]#

递归增量复制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost 文件管理和目录管理]# cp -r -u 文件管理/ 文件管理3
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 9 files
[root@localhost 文件管理和目录管理]#

需要注意的是-u只会比较一级子目录下的不同,不会递归子目录树上的不同,如果没有搭配-r参数一起使用的话,可能会达不到效果:

1
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
44
45
46
47
48
49
50
51
52
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3
└── 文件管理
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

5 directories, 9 files
[root@localhost 文件管理和目录管理]# rm -rf 文件管理3/文件管理/备份/
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3
└── 文件管理
├── HelloWorld2.c
└── HelloWorld.c

4 directories, 7 files
[root@localhost 文件管理和目录管理]# cp -u 文件管理/ 文件管理3
cp: 略过目录"文件管理/"
[root@localhost 文件管理和目录管理]# tree -N
.
├── ht.c
├── 文件管理
│   ├── HelloWorld2.c
│   ├── HelloWorld.c
│   └── 备份
│   ├── p1.c
│   └── p2.c
└── 文件管理3
└── 文件管理
├── HelloWorld2.c
└── HelloWorld.c

4 directories, 7 files
[root@localhost 文件管理和目录管理]#

复制目录示例

将目录work.d复制为bak.d
若bak.d不存在,执行:

1
cp -r work.d bak.d

若bak.d已存在,执行:

1
cp -r work.d/* bak.d

增量拷贝

将work.d中的内容增量拷贝到备份目录bak.d中

1
cp -ruv work.d/* bak.d

命令touch

将文件的最后一次修改时间设置为当前时间,但不修改文件内容。例如:

1
touch *.[ch]

rsync:数据备份工具(增量拷贝工具)

rsync功能

远程同步remote sync,可以镜像整个目录树

  • 问题
    • 网络中两个主机A和B,都有同一个二进制的大型数据文件big.dat,文件在A上做了改变成为了新版本的big.dat,需要让B也得到新文件
  • 优化的流程,增量文件传输,效率高
    • rsync用一精巧的算法,将文件分块,在两主机间传播数据块的hash值,据此推出两版本文件之间区别,使得网络只传输文件的增、删、改部分
  • Windows下的也有类似工具

tree命令中文乱码问题

tree打印目录树时,遇到中文的目录或文件名时,打印的是\数字

1
2
3
4
5
6
7
8
9
10
11
[root@localhost Linux_Test]# tree 文件管理和目录管理/
\346\226\207\344\273\266\347\256\241\347\220\206\345\222\214\347\233\256\345\275\225\347\256\241\347\220\206/
└── \346\226\207\344\273\266\347\256\241\347\220\206\345\222\214\347\233\256\345\275\225\347\256\241\347\220\2062
├── HelloWorld2.c
├── HelloWorld.c
└── \345\244\207\344\273\275
├── p1.c
└── p2.c

2 directories, 4 files
[root@localhost Linux_Test]#

解决方案:tree -N

man tree查看相关选项,可以看到使用-N选项可以按原样打印不可打印的字符,而不是转义的八进制数。

1
2
3
4
5
......
FILE OPTIONS
......
-N Print non-printable characters as is instead of as escaped octal numbers.
......

打印效果:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost Linux_Test]# tree -N 文件管理和目录管理/
文件管理和目录管理/
└── 文件管理和目录管理2
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

2 directories, 4 files
[root@localhost Linux_Test]#

参考资料

https://www.jianshu.com/p/52a4cedcfea0

问题:vim搜索的关键字不会自动取消高亮显示

在vim中使用正则表达式搜索时,匹配的关键字会高亮显示。但当我们不需要搜索时,这些匹配的关键字还是高亮。退出文件后再次用vim打开该文件,还是会高亮显示。

解决方案

在末行模式下输入:

1
:noh

或者

1
:nohlsearch

图片

参考资料

https://www.jianshu.com/p/d0a287a26866
https://blog.csdn.net/k7arm/article/details/77370181