Linux 文件系统简介

当我们初次照葫芦画瓢在 VMware Workstation pro 的虚拟机中安装了 CentOS 7 系统并登陆 CentOS 系统后,就需要掏出手机打开高德地图导航,扫部滴滴电动车,开启 CentOS 神奇之旅!我在哪里?我要去哪?我要干什么?

CentOS 是类 Unix 的 Linux 操作系统中最著名的分发版本之一。Linux 文件系统架构看起来像一个倒置的树,以根目录(/)起始,逐渐展开。

# 输入以下命令再按回车(`enter`)。将会输出 ascii 字符图形的目录结构。
cd /
tree
...		# 输出内容很多,自行执行。

# 输入以下命令将显示根目录及其一级子目录。
tree -L 1 /
# 以下为输出
/
├── bin -> usr/bin		# 二进制可执行文件。
├── boot				# 放置 linux 系统的内核文件和引导文件。
├── dev					# 设备文件,比如磁盘,终端等。
├── etc					# 配置文件目录
├── home				# 普通用户家目录的父目录。
├── lib -> usr/lib				# 链接库文件目录
├── lib64 -> usr/lib64			# 64 位链接库文件目录
├── media				# 扩展存储自动挂载目录。
├── mnt					# 手动挂载磁盘或分区目录。
├── opt					# 一般作为编译软件的安装目录。
├── proc				# 一个虚拟目录,用于包含内核、计算机硬件和其它信息。
├── root				# 超级管理员 `root` 的家目录。请注意与根目录 `\` 区分。
├── run					# 系统进程存放临时数据的目录。
├── sbin -> usr/sbin			# 用于保存系统管理员使用的程序的目录。
├── srv							# 早期存放服务的数据的目录。
├── sys							# 另外一个虚拟目录,存放连接到计算机的设备的目录。
├── tmp							# 临时文件目录。
├── usr							# 存放应用程序的目录。
└── var							# 存放数据经常变化的文件的目录,如日志。

注: 如果显示命令未找到 `bash: tree: command not found...`,请先执行此命令`yum install -y tree` 来安装 `tree` 命令。

启动电动车开始探索!

先熟悉一下环境,和各位命令打个照面。有些人很快就熟悉了,有些人要熟悉只是个时间问题,还有些人我们永远看不懂!

ls

ls [option] [dir]
list directory contents.
显示目录内容。

选项:

-l			# 长格式显示文件信息。
-d			# 显示目录本身信息。
-a			# 显示所有文件,包括隠藏文件和 `.`,`..` 这两个文件。
-A  		# 显示除了 `.`,`..` 这两个文件之外的所有文件,包含隐藏文件。

-t	按修改时间排序显示文件。

示例:

# 以长格式输出当前所在目录内的文件信息,输入以下命令:
ls -l

...
-rw-r--r--.  1 root root     9580 Sep  18 18:18 Hello-Lucky
...

以长格式显示的文件信息分为九个区段:

第一个区段:
第一个字符表示文件类型,普通文件,目录等;

第二个区段:
第二到第十位字符的这九位字符称为文件权限模式位,表示文件的访问权限。其中每三个字符位分别表示为文件的属主、所属群组和其他所有人三个类别划分集合的读、写、执行或无权限等。

第三个区段:
也就是第十一个字符位,此样例中的那个点。其所表示的含义为:

系统开启 SElinux,文件未应用 ACL,此区段显示为 `.`;
系统关闭启 SElinux,之后创建的文件,也没未应用 ACL,此区段为空,之前开启 SElinux 创建的文件人然显示为 `.`;
无论系统是否开启 SElinux,只要文件应用了 ACL,此区段显示为 `+`;

第四个区段:
文件的链接数或目录的第一级子目录数;

第五个区段:
文件的属主;

第六个区段:
文件的所属群组;

第七个区段:
文件大小(单位:字节);

第八个区段:
文件的修改时间;

第九个区段:
文件名称。

文件类型常见的有:

\-			# 普通文件
d			# 目录
l			# 链接文件
c			# 字符文件(用来表示串行端口的接口设备,例如伪终端等)
b			# 块文件(用来表示磁盘等)
s			# 套接字文件(通常用在网络数据连接)
p			# 管道文件

管道文件又分为有名管道和无名管道

有名管道:

在磁盘上会存储一个管道文件表示(inode 存于内存上),但它并不会占据磁盘空间(block),数据并不会存储到磁盘上。

创建有名管道:

示例:

useradd another_user								# 添加一个用户
mkfifo /tmp/named.pipe1								# 创建有名管道
echo "Hello World\!" > /tmp/named.pipe1				# 向管道输入信息

su another_user										# 切换到 another_user
cat < /tmp/named_pipe1								# 查看从管道传送的信息

another_user 用户将显示 Hello World! 信息。

无名管道:

无名管道不拥有管道文件。

cat /etc/passwd | grep "root"			# 查看 /etc/passwd 文件,并通过无名管道 | 传送
										# 信息到命令 grep,以显示匹配 root 关键字的信息

将显示 `root:x:0:0:root:/root:/bin/bash` 信息。

mkdir

mkdir [OPTION]... DIRECTORY...
make directories
创建目录

-p			# 按需创建父目录。

示例:

mkdir test_dir			# 创建目录 test_dir
mkdir one/two			# 创建目录 two 及其 父目录 one。

cd

cd [option] [dir]
change the current directory to dir.
更改当前目录到 dir。cd 命令时 bash shell 内置命令。

-L			# cd 进入链接目录。默认选项。
-P			# cd 解析链接目录,进入物理路径目录。

特殊字符

.			# 表示当前目录
..			# 表示上一级目录
~			# 表示用户属主目录
-			# 表示之前所在的目录


cd      	# 不加参数,表示返回用户家目录,等同 `cd ~`。
cd -    	# 返回之前所在的目录。

假设链接目录 ln_dir 链接 /home/user_home_directory/Desktop/,并且其 ln_dir 位于 /home/user_home_directory/test/ln_dir,则进入链接目录,pwd 命令将显示当前目录为链接目录路径 /home/user_home_directory/test/ln_dir

# 创建环境
cd
mkdir test
cd test
ln -s /home/user_home_directory/Desktop/ln_dir

# 检测效果
cd -L ln_dir
pwd

假设链接目录 ln_dir 链接 /home/user_home_directory/Desktop/,并且其 ln_dir 位于 /home/user_home_directory/test/ln_dir,则进入链接目录,pwd 命令将显示当前目录为链接目录路径/home/user_home_directory/Desktop/

cd -
cd -P abc
pwd

pwd

pwd [option] [dir]
print name of current/working directory
打印当前/工作目录的路径。

-L			# 打印的目录路径可以为链接目录路径。
-P			# 打印的目录路径不可以为链接目录路径,也就是打印目录的物理路径。

echo

display a line of text
显示一行文本。

-n			# 不输出默认在行尾输出的换行符。
-e			# 开启转译字符解析。
-E			# 关闭转译字符解析。
如果 `-e` 选项生效,则可以识别以下转译序列:

    `\\`	反斜线
 	`\a`	响铃符(BEL)
	`\b`	退格符
	`\c`	不再产生进一步的输出(如解析此字符,此字符后信息不再输出,也没有换行)
	`\f`	换页符
	`\r`	回车符
	`\n`	换行符
	`\t`	水平制表符
	`\v`	垂直制表符

	`\NNN`	字符的ASCII代码为NNN(八进制)
	`\xHH`	字符的ASCII代码为NNN(十六进制)


	# 显示 Hello
	echo 'Hello'
	
	# 乐一下
	echo -e "\033[?25l"
	# 有惊喜
	echo -e "\033[?25h"

cat

concatenate files and print on the standard output.
连接文件并输出到屏幕。

没有文件名参数或文件名为连字符 -时,则读取标准输入。

-A, --show-all		# 输出不可打印字符,包括制表符和换行。等同 -vET。
-b, --number-nonblank		# 尽对非空行列行号。覆盖 -n。
-e					# 输出不可打印字符和换行符。等同 `-vE`。
-E, --show-ends		# 在行尾以 $ 符号显示换行符。
-n, --number		# 显示时列行号。
-s, --squeeze-blank			# 压缩重复的空行。
	
-t					# 等同 -vT。
-T, --show-tabs		# 输出时以 `^I` 显示制表符。

--help				# 显示帮助。
--version			# 显示命令版本。

cat 一般用于查看内容比较少的文本文件,或配合重定向符号创建文本文件(Shell 编程中较多使用)。查看非打印字符是否是你所需要的,比如制表符号和行尾的换行符是否是符合 linux 标准的 \n

示例:

cat > test1.txt << EOF		# 在当前目录生成 test1.txt 文本文件。

abc
bbc
ccc
EOF

cat -A test1.txt			# 查看文本文件内容。

unix2dos test1.txt			# 将文本文件从 unix 格式转换为 DOS 格式。

cat -A test1.txt			# 查看 DOS 格式文本文件的换行符号。

cp

cp [OPTING] SOURCE DEST

copy files and directories
复制文件和目录。

-a			# 此参数的效果等同 -dpR。
-d			# 可复制符号链接,不会破坏链接文件和源文件链接关系。
-f			# 强制复制文件或目录,不论目标文件是否存在。
-i			# 覆盖既有文件之前先询问用户。
-l			# 对源文件建立硬链接,而非复制文件。
-p			# 保留源文件或目录的属性。
-R/r		# 递归处理,将指定目录下的所有文件与子目录一并处理。
-s			# 对源文件建立符号连接,而非复制文件(指定绝对路径)。
-u			# 使用这项参数后只会在源文件的更改时间较目标文件要新的时候或是目标文件并不存在时,才复制文件。
-S			# 在备份文件时,用指定的后缀 “SUFFIX” 代替文件的默认后缀。
-b			# 复制文件,如有同名文件,则在文件名后添加后缀 ~。
-v			# 详细显示命令执行的操作。

示例:

cp test1.txt /tmp/test1.txt.backup
cp test1.txt /tmp			
ls -l /tmp/test1.*				# 查看两次复制结果。

cp -i test1.txt /tmp		# 交互模式复制,提示是否覆盖。

mkdir -p  a/b/c				
cp -R a /tmp				# 递归复制 a 目录及其下目录和文件。
ll /tmp/a/b					# 查看递归复制的结果。

cp -b test1.txt /tmp			
ll /tmp/test1.*				# 不覆盖同名文件,生成新文件 /tmp/test1.txt~,再次复制则覆盖。

cp test1.txt /tmp/
echo "add something into sour_file" >> test1.txt
cp -u test1.txt /tmp/		# 更新目标文件。
	
cat /tmp/test1.txt						
echo "add something into dest_file" >> test1.txt
cp -u test1.txt /tmp/					# 目标文件比源文件新,则不复制。

cp -S ".`date +%F`" test1.txt /tmp/				# 复制文件并添加指定后缀。
ll /tmp/test1.*

注: 最好用的选项是 -a,递归复制并且完全保留了源文件的属性。

rm

rm [OPTION]... [FILE]...

remove files or directories
移除文件或目录

-f/--force				# 强制删除,删除前不提示。
-i						# 交互式删除,删除前提示。
-r/R					# 递归删除。

示例:

touch one.txt
rm	one.txt				# 删除一个文件。

mkdir -p a/b/c
cp test1.txt a/b/c
rm -R a					# 删除 a 目录及其下所有目录和文件。

注: rm 可以删除空目录,但删除有文件的目录必须使用 -r/R 选项。用 -r/R 选项使用此命令,应该是最危险命令操作,没有之一。


rmdir

rmdir [OPTION]... DIRECTORY...

remove empty directories
移除空目录。

-p			# 删除目录及其子目录。

示例:

mkdir -p a/b/c
rmdir -p a/b/c			# 正好是 mkidr -p 的反操作。

less / more

查看大文件,分屏显示,可以使用键盘翻屏。

空格	显示下一屏内容。
	b	显示上一屏内容。
	f	显示下一屏内容。

head

head [OPTION]... [FILE]...

output the first part of files
输出文件前部分,默认 10 行。

示例:

head -5 /etc/passwd				# 输出指定文件前 5 行信息。

tail

tail [OPTION]... [FILE]...

output the last part of files
输出文件的末尾部分,默认 10 行。

示例:

tail -5 /etc/passwd				# 输出指定文件最后 5 行信息。

wc

wc [OPTION]... [FILE]...

print newline, word, and byte counts for each file
输出每个文件的行数,词数或所用字节数。

-c			# 输出文件的字节数。
-m			# 输出文件的字符数。
-l			# 输出文件的行数。
-w			# 输出文件单词数。

示例:

wc -l /etc/passwd			# 查看文件有多少行。

grep

grep [OPTIONS] PATTERN [FILE...]

print lines matching a pattern
输出文件内匹配所指定模式的行。

-i			# 匹配时,忽略大小写。
-v			# 显示不匹配的行。
-n			# 在每个匹配行前面加上行号。
-c			# 仅打印匹配行的总数 。

注:这是一个非常强大的查询命令,关联非常强大的正则模式,此处先简单介绍几个选项。

示例:

grep root /etc/passwd			# 输出匹配关键字 root 的行。

cat > test2.txt << EOF
abc
ABc
EOF

grep -i 'abc' test2.txt			# 输出匹配关键字 abc 的行,并且忽略大小写。

重定向

>			# 将输出输出到指定文件、命令或设备。
>>			# 将输出以追加的方式输出到指定文件、命令或设备。
<			# 将输入输入到指定文件、命令或设备。

示例:

echo 'hello world' > test3.txt	# 将字符串输入到指定文件。指定文件为新文件则创建,已有文件则覆盖其内容。

echo 'bye' >> test3.txt			# 将字符串以附加方式输入到指定文件。

将键盘输入的信息输入到 cat 命令,cat 命令再输出到指定文件,EOF 为输入结束符。如未指定输入结束符,按 ctrl + d 也可以结束输入。
cat > test2.txt << EOF
abc
ABc
EOF

touch

change file timestamps or create file
更改文件时间戳或创建文件。

-a			# 仅更改访问时间
-m			# 仅更改修改时间

每个文件具有三个时间: 访问时间(access time)、修改时间(modify time)、属性更改时间(change time)。当文件被首次创建时间时,三个时间相同;当用 cat、less、more 查看时,访问时间被记录;当更该文件属性,如权限等时,属性更改时间被记录;当修改文件内容时,修改时间和属性更改时间都同时记录。

touch stamp_test.txt	# 是新文件,则创建,三个时间相同。
stat stamp_test.txt		# stat 查看文件状态,其中包括三个时间记录。

...
Access: 2020-11-12 17:26:25.592183057 +0800
Modify: 2020-11-12 17:26:25.592183057 +0800
Change: 2020-11-12 17:26:25.592183057 +0800

cat stat stamp_test.txt 
stat stamp_test.txt		# 执行 cat 命令后,访问时间被修改。

...
Access: 2020-11-12 17:33:21.041257391 +0800
Modify: 2020-11-12 17:26:25.592183057 +0800
Change: 2020-11-12 17:26:25.592183057 +0800

chmod o+w stat stamp_test.txt	# chmod 修改文件权限。
stat stamp_test.txt             # 执行 chmod 命令后,属性更改时间被修改。

...
Access: 2020-11-12 17:33:21.041257391 +0800
Modify: 2020-11-12 17:26:25.592183057 +0800
Change: 2020-11-12 17:37:42.467079091 +0800

echo "hello" >> stamp_test.txt	# 修改文件内容。
stat stamp_test.txt             # 修改时间和属性更改时间被修改。

...
Access: 2020-11-12 17:33:21.041257391 +0800
Modify: 2020-11-12 17:39:44.790867299 +0800
Change: 2020-11-12 17:39:44.790867299 +0800

alias

创建命令别名。

-p			# 以 `name=value` 键值对的格式输出已定义的命令别名。

alias 不加参数将显示所有已设置的别名。

在命令行定义的别名要在其它会话中生效,必须将整个别名定义添加到 shell 配置文件 /etc/bashrc 或 shell 个人配置文件 .bashrc 文件中。

# 欢迎进入 FUN CLUB !
alias gbq='echo -e "\033[?25l"'
alias gbl='echo -e "\033[?25h"'

unalias

remove each name from the list of defined alias.
移除指定的别名。

-a			# 移除所有已经定义的别名。

同样删除别名要在其它会话中生效,必须修改 shell 配置文件 /etc/bashrc 或 shell 个人配置文件 .bashrc 文件。


gzip

compress or expand files
压缩或解压缩文件。

-c			# 将压缩结果重定向到其它文件,保留原文件。
-d			# 解压缩。
-r			# 递归压缩目录内文件,只压缩文件,不会压缩目录。
-1~9		# 指定压缩级别,-1 最快压缩,-9 最大压缩,更消耗 cpu ,默认为 6。

示例:

cp /etc/passwd ./com_test		# 复制文件。
gzip com_test				# 压缩文件,生成压缩文件 com_test.gz,源文件被删除。

gzip com_test.gz			# 解压缩文件。

gzip -c com_test >> com_test_bk.gz	# 指定压缩后文件名,源文件保留。

cp -r /etc/yum.repos.d/ ./test_dir	# 复制目录。
gzip -r test_dir			# 递归压缩目录内文件。

bzip2

压缩或解压缩文件。

-k			# 保留源文件。默认选项。
-d			# 解压缩文件。
-1~9		# 指定压缩级别。

示例:

bzip2 com_test		# 压缩文件,保留源文件并生成文件 com_test.bz2。

zip

打包并压缩文件。

-r			# 递归压缩目录。
-m			# 删除源文件。默认不删除。

示例:

gzip -rd test_dir					# 解压开始用 gzip 递归压缩目录内文件。
zip -rm test_dir.zip test_dir		# 递归压缩目录和文件,并删除源文件。

unzip		解压 zip 压缩的文件。

示例:

unzip test_dir.zip	# 解包和压缩。

tar

an archiving utility
归档工具

-c			# 创建新的 tar 包。
-f			# 指定 tar 包名。
-r			# 结合 f 选项,添加文件到归档文件。
-z			# gzip 格式压缩归档包, 后缀为 `.tar.gz`。
-j			# bzip2 格式压缩归档包,后缀为 `.tar.bz2`。
-p			# 保留文件的权限和属性。
-x			# 从归档文件中析取文件。
-t			# 只查看 tar 包中的目录和文件,不从归档中析取文件。
-C			# 析取文件到指定目录。
--remove-files			# 归档后删除源文件。

示例:

tar czvf a.tar.gz /etc				# 归档 `/etc` 目录并压缩。
tar xzvf a.tar.gz -C ./tar_test		# 从归档中析取文件到 `./tar_test` 目录。

file

determine file type
检测文件的类型。

示例:

file /dev/tty
/dev/tty: character special (5/0)		# 特殊字符文件。

stat

display file or file system status
显示文件或文件系统的状态。

# 请查看上面 touch 命令的例子。

which

shows the full path of (shell) commands.
显示(shell)命令的完整路径。

which cd
/usr/bin/cd

注:无法区分 bash 内置命令和外部命令。


whereis

locate the binary, source, and manual page files for a command
查找一个命令的二进制文件及其手册页位置。

示例:

whereis cd
cd: /usr/bin/cd /usr/share/man/man1/cd.1.gz /usr/share/man/man1p/cd.1p.gz

whereis whatis
whatis: /usr/bin/whatis /usr/share/man/man1/whatis.1.gz

注:无法区分 bash 内置命令和外部命令。


whatis

display one-line manual page descriptions
查询并显示手册页命令的单行描述。

示例:

whatis cd
cd (1)               - bash built-in commands, see bash(1)
cd (1p)              - change the working directory

whatis whatis
whatis (1)           - display one-line manual page descriptions

注:显示了 bash 和 外部命令。


apropos

search the manual page names and descriptions
搜索手册页中的命令名称和描述来查找命令。

示例:

# 当我们记不清命令名称时,我们就可以输入部分以查找命令全名。
# 比如此页面中的三个压缩命令。
apropos zip
...
bzip2 (1)            - a block-sorting file compressor, v1.0.6
...
funzip (1)           - filter for extracting from a ZIP archive in a pipe
gunzip (1)           - compress or expand files
gzip (1)             - compress or expand files
...
zip (1)              - package and compress (archive) files
...
# 在查询的结果中寻找你记不太清的命令。

man

manual
手册页工具。

whatis,whereis,apropos 都是 man 命令的部分实现,只是更容易记忆。

手册页分为 9 大类,请用命令 man man 查询以下类似信息:

1   Executable programs or shell commands				# 可执行程序或 shell 命令。
   2   System calls (functions provided by the kernel)		# 系统调用。
   3   Library calls (functions within program libraries)	# 链接库调用。
   4   Special files (usually found in /dev)						# 特殊文件。
   5   File formats and conventions eg /etc/passwd			# 文件格式和约定。
   6   Games																	# 游戏。
   7   Miscellaneous  (including  macro  packages  and  conventions), e.g.
       man(7), groff(7)		# 杂项。
   8   System administration commands (usually only for root)		# 系统管理员命令。
   9   Kernel routines [Non standard]			# 内核线程。

man [1-9] command

man 1 cd

reboot

重启电脑


shutdown

关机

shutdown -r now			# 现在立刻重启电脑。
shutdown -h now			# 立刻关机。
shutdown -h +10 "I will shutdown the service in 10 minutes!"
# 10 分钟后关机,并广播关机信息。