文件元数据和节点表结构

文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块

inode表结构

文件由元数据和数据块组成
文件的元数据(meta data):每个文件的属性信息,比如:文件的大小,时间,类型等。
元数据是存放在node(index node)表中,node表中有很多条记录组成,第一条记录对应的存放了一个文件的元数据信息。第一个node表记录对应的保存了以下信息:
*inode number 节点号(系统自动分配,每个文件唯一拥有;会被重复使用,可能会被用光,节点编号用完时也会显示空间不足)
清空大文件:cat /dev/null > /var/log/huge.log;rm -f /var/log/huge.log
*文件类型/权限/UID/GID
*链接数(指向这个文件名路径名称个数)
*该文件的大小和不同的时间戳
*指向磁盘上文件的数据块指针
*有关文件的其他数据

  • 目录是个特殊文件,目录文件的内容保存了此目录中文件的列表及inode number对应关系

*文件引用一个是 inode号
*人是通过文件名来引用一个文件
*一个目录是目录下的文件名和文件inode号之间的映射

硬(hard)链接

硬链接本质上就给一个文件起一个新的名称,实质是同一个文件
ln`` filename [linkname ]
image.png

符号 ( symbolic ) 或 软 (soft)链接

一个符号链接指向另一个文件,就像 windows中快捷方式,软链接文件和原文件本质上不是同一个文件
ln -s`` filename [linkname]
image.png

  1. ln -s /data/dir /data/dirlink #绝对路径
  2. cd /data #相对路径
  3. ln -s ../data/dir /root/dirlink
  4. rm -rf /data/dirlink #删除软链接本身,不会删除源目录内容
  5. rm -rf /data/dirlink/ #删除源目录的文件,不会删除链接文件(注意!)
  6. readlink /data/dirlink #查看链接文件指向的原文件

硬链接和软链接区别总结

硬链接 软连接
本质 是同一个文件起了多个名字 不是同一个文件
文件类型 和源文件相同 链接文件和源文件无关
跨设备 不支持 支持
inode 相同 不同
链接数 创建新的硬链接,链接数会增加
删除硬链接,链接数减少
创建或删除,链接数不会变化
删除源文件 只是链接数减一,但链接文件的访问不受影响 链接文件将无法访问
文件夹 不支持 支持
相对路径 原始文件相对路径是相相对于当前工作目录 原始文件相对路径是相相对于链接文件的相对路径

生产案例

案例1:提示空间满 No space left on device,但 df 可以看到空间很多,为什么?
案例2:提示空间快满,使用rm删除了很大的无用文件后,df仍然看到空间不足,为什么?如何解决?

标准输入和输出

  • 程序:指令+数据
  • 读入数据:Input

    输出数据:Output 
    
  • 打开的文件都有一个fd: file descriptor (文件描述符)

我们知道在Linux系统中一切皆可以看成是文件,在操作这些所谓的文件的时候,我们每操作一次就找一次名字,这会耗费大量的时间和效率。所以Linux中规定每一个文件对应一个索引,这样要操作文件的时候,我们直接找到索引就可以对其进行操作了。
文件描述符(file descriptor)就是内核为了高效管理这些已经被打开的文件所创建的索引,用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符来实现。同时还规定系统刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。这意味着如果此时去打开一个新的文件,它的文件描述符会是3,再打开一个文件文件描述符就是4……
Linux给程序提供三种 I/O 设备
image.png

[root@CentOS ~]$ ll /dev/std*
lrwxrwxrwx. 1 root root 15 Jul 19 19:39 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx. 1 root root 15 Jul 19 19:39 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Jul 19 19:39 /dev/stdout -> /proc/self/fd/1
[root@CentOS ~]$ tail -f /var/log/messages    (#运行tail程序,查阅一个正在改变的日志文件)
[root@CentOS ~]$ ll /proc/`pidof tail`/fd    (#pidof命令用于查找指定名称进程的进程号id号)
total 0
lrwx------. 1 root root 64 Jul 26 14:23 0 -> /dev/pts/7
lrwx------. 1 root root 64 Jul 26 14:23 1 -> /dev/pts/7
lrwx------. 1 root root 64 Jul 26 14:23 2 -> /dev/pts/7
lr-x------. 1 root root 64 Jul 26 14:23 3 -> /var/log/messages
lr-x------. 1 root root 64 Jul 26 14:23 4 -> anon_inode:inotify

I/O重定向

I/O重定向:将默认的输入,输出或错误对应的设备改变,指向新的目标

标准输出、标准错误重定向 (>,2>)

STDOUT,STDERR重定向到指定文件,而非默认的当前终端:命令 操作符号 文件名
1> 或 > 把STDOUT重定向到文件 >> 追加STDOUT重定向至文件
2> 把STDERR重定向到文件 2>> 追加STDERR重定向至文件
(#文件如果已经存在会被覆盖)
set -C 禁止将内容覆盖已有文件,但可追加, 利用 >| 仍可强制覆盖
set +C 允许覆盖,默认

[root@CentOS ~]$ ls 1> /dev/pts/7    (#标准输出重定向到文件)
[root@CentOS ~]$ ls > /dev/pts/7    (#同上)
[root@CentOS ~]$ ls > /data/zyylist.txt    (#文件不存在则新建一个文件,标准输出重定向到该文件里面)
[root@CentOS ~]$ cat /data/zyylist.txt
anaconda-ks.cfg Desktop Documents Downloads initial-setup-ks.cfg Music 
Pictures Public Templates Videos 
[root@CentOS ~]$ whoami > /data/zyylist.txt    (#文件如果已经存在会被覆盖)
[root@CentOS ~]$ cat /data/zyylist.txt
root
[root@CentOS ~]$ echo "我是个大美女" >> /data/zyylist.txt    (可以用>>追加定向输出内容)
[root@CentOS ~]$ cat /data/zyylist.txt
root
我是个大美女
[root@CentOS /data]$ wall warnning > all.og    (在屏幕上显示也不一定是标准输出)

[root@CentOS /data]$ set -C
[root@CentOS /data]$ who > /data/zyylist.txt
-bash: /data/zyylist.txt: cannot overwrite existing file
[root@CentOS /data]$ set +C
[root@CentOS /data]$ who > /data/zyylist.txt
[root@CentOS /data]$ cat /data/zyylist.txt
root     :0           2021-07-19 19:39 (:0)
root     tty2         2021-07-20 14:00

> 文件 会清空数据,生成空文件(但并不是所有shell版本都支持)

[root@CentOS ~]$ > /data/zyylist.txt    (#清空数据,变成空文件,危险!)    (touch是可以安全创建空文件的)
[root@CentOS ~]$ cat /data/zyylist.txt
[root@CentOS ~]$ ll /data/zyylist.txt
-rw-r--r--. 1 root root 0 Jul 27 15:39 /data/zyylist.txt
[root@CentOS ~]$ > /data/f1.txt    (#文件不存在则生成一个空文件)
[root@CentOS ~]$ ll /data/f1.txt
-rw-r--r--. 1 root root 0 Jul 27 15:43 /data/f1.txt

[root@CentOS ~]$ cat /dev/null > /data/f2.txt        (#通用,清空或创建空文件)
[root@CentOS ~]$ ll /data/
-rw-r--r--.   1 root root    0 Jul 27 17:01 f2.txt

磁盘空间如果被挤满后果很严重,需做好监控, 工作中清除大文件释放空间可以:cat /dev/null >`` /data/bigfile.log

①各自定向至不同位置:

COMMAND ``>`` /path/file1 ``2>`` /path/error2

[root@CentOS /data]$ ls /data/ /xxx > f1.txt 2> f2.txt
[root@CentOS /data]$ cat f1.txt
/data/:
all.og
backup
backup2021-07-22
etc
f1.txt
f2.txt
rootdir
zyylist.txt
[root@CentOS /data]$ cat f2.txt
ls: cannot access /xxx: No such file or directory

②输出为同一个文件

&> 把标准输出和错误都重定向
>& 把标准输出和错误都重定向,即和上面功能一样,建议使用上面方式
&> 覆盖重定向
&>> 追加重定向
COMMAND ``>`` f1.txt ``2>&1 (顺序很重要)
COMMAND ``>>`` /path/to/file.out ``2>&1

[root@centos8 ~]#ls /data /xxx > /data/all.log 2>&1        (#将标准输出和错误都重定向到同一个文件)
[root@centos8 ~]#ls /data /xxx 2> /data/all.log 1>&2    (#同)
[root@centos8 ~]#ls /data /xxx &> /data/all.log     (#同)
[root@centos8 ~]#ls /data /xxx 2>&1 > /data/all.log    (×,只能打印标准输出)
ls: cannot access '/xxx': No such file or directory

#隐藏不希望在屏幕上显示的结果:passwd zhuyuany ``&> /dev/null

③合并多个命令结果至一文件()

[root@centos8 ~]#( cal 2019 ; cal 2020 ) > all.txt 
[root@centos8 ~]#{ ls;hostname;} > /data/all.log

标准输入重定向(<)

利用<将标准输入重定向,按ctrl+d离开,可使用文件夹来代替键盘的输入
案例1

[root@CentOS ~]$ echo 5*7 > 8-27.txt
[root@CentOS ~]$ bc < 8-27.txt    (#输入8-27.txt文件的内容作为bc的参数)
35
[root@CentOS ~]$ bc < 8-27.txt >zyy    (#输入8-27.txt文件的内容,输出内容放到zyy文件中 #方法①)
[root@CentOS ~]$ cat zyy
35
[root@CentOS ~]$ bc > zyy < 8-27.txt    (#方法②)
[root@CentOS ~]$ cat zyy
35
[root@CentOS ~]$ bc > 8-27.txt < 8-27.txt    (文件名相同则文件清空)

案例2

(*ubuntu安装mail:sudo apt install mailutils    *CentOS8安装:dnf install mailx)
(mail命令是命令行的电子邮件发送和接收的工具。mail命令是个软链接,真实的程序文件是mailx)
[root@localhost ~]$ mail    (默认收到的邮件)
No mail for root
[root@localhost ~]$ man mail
[root@localhost ~]$ ss -ntl    (用来获取socket统计信息;其中邮件端口号默认为25)
[root@localhost ~]$ mail -s test zhuyuany    (发送标题为test的邮件,内容以.结束)
i am zyy
.
EOT
/usr/sbin/sendmail: No such file or directory
[root@localhost ~]$ dnf install postfix -y    
[root@localhost ~]$ systemctl start postfix    (需启动邮件服务功能才能使用该命令)
[root@localhost ~]$ ss -ntl
State   Recv-Q Send-Q   Local Address:Port Peer  Address:Port
LISTEN 0      100        127.0.0.1:25          0.0.0.0:*  
LISTEN 0      100            [::1]:25             [::]:* 

[root@localhost ~]$ nano mail.txt
[root@localhost ~]$ mail -s test zhuyuany < mail.txt    (#输入mail.txt文件的内容作为邮件的内容)

多行重定向

`cat > file`  (cat不加文件是输入啥查看啥)<br />使用 "<< 终止词" 命令从键盘把多行重导向给STDIN,直到终止词位置之前的所有文本都发送给STDIN<br />其中终止词可以是任何一个或多个符号,比如:!,@,$,EOF(End Of File)等,其中EOF 比较常用
[root@centos8 ~]$ cat > mail.txt    (单行重定向,写一行重定向保存一行)
my
name
is
zyy
[root@centos8 ~]$ cat > zyy.1 <<EOF    
> zhuyuany
> beautiful
> EOF

tr 转换和删除字符

tr [OPTION]… SET1 SET2
-d —delete:删除所有属于第一字符集的字符
-s —squeeze-repeats:把连续重复的字符以单独一个字符表示,即去重
-t —truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符
-c –C —complement:取字符集的补集
image.png image.png

  • tr ‘a-z’ ‘A-Z’< /etc/issue #该命令会把/etc/issue中的小写字符都转换成大写字符
  • tr –d abc < /etc/fstab #删除fstab文件中的所有abc中任意字符
  • df > df.log

    #`tr -s ' ' < df.log` #将df.log文件中空格去重<br />      #`tr -s ' ' : < df.log` #将df.log文件中空格变成:
    
  • 将 Windows的文本 转化 Linux 的文本格式 :#tr -d '\r' < windows.txt > linux.txt

在Windows下换行时,有两个字符回车(/r)和换行(/n)。
但在Linux下,只有一个换行(/n)
也可使用unix2dos和dos2unix命令进行格式的转换

管道

管道“|”用来连接多个命令

命令1 | 命令2 | 命令3 | …
将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
所有命令会在当前shell进程的子shell进程中执行
组合多种工具的功能

[root@centos8 ~]$ df >df.log
[root@centos8 ~]$ tr -s ' ' < df.log     (#通过df.log这个文件将df的输出作为tr的输入)
[root@centos8 ~]$ df | tr -s ' '    (#通过"|"来实现将df的输出作为tr的输入)

[root@centos8 ~]$ echo {1..100} |tr ' ' + |bc
5050
[root@centos8 ~]$ seq -s + 1 100 |bc
5050

&> /dev/null实现非交互形式,批量处理提高效率

[root@centos8 ~]$ cat pw.txt
zyy
[root@centos8 ~]$ cat pw.txt | passwd --stdin wang
passwd: Unknown user name 'wang'.
[root@centos8 ~]$ cat pw.txt | passwd --stdin zhuyuany
Changing password for user zhuyuany.
passwd: all authentication tokens updated successfully.
[root@centos8 ~]$ cat pw.txt | passwd --stdin zhuyuany &> /dev/null

标准错误用2>&1 ||&来转发

[root@centos8 ~]$ ls /data /xxx | tr 'a-z' 'A-Z'        (#标准错误默认不能通过管道转发)
ls: cannot access '/xxx': No such file or directory
/DATA:
BACKUP
OUTPUT.TXT
[root@centos8 ~]$ ls /data /xxx |& tr 'a-z' 'A-Z'    
[root@centos8 ~]$ ls /data /xxx 2>&1 | tr 'a-z' 'A-Z'        (#用"2>&1 |" 或"|&" 实现)
LS: CANNOT ACCESS '/XXX': NO SUCH FILE OR DIRECTORY
/DATA:
BACKUP
OUTPUT.TXT

管道中的”-“符号

tar -cvf - /home | tar -xvf -

tee 重定向到多个目标

命令1 | tee [-a ] 文件名 | 命令2 …..:可以把命令1的STDOUT保存在文件中,做为命令2的输入(-a 追加)
功能:保存不同阶段的输出
复杂管道的故障排除
同时查看和记录输出

[root@centos8 ~]$ cat <<eof | tee /etc/motd
> zyy
> beautiful
> very
> eof
zyy
beautiful
very