文件元数据和节点表结构
文件名仅是为了方便人们的记忆和使用,系统或程序通过 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 ]
符号 ( symbolic ) 或 软 (soft)链接
一个符号链接指向另一个文件,就像 windows中快捷方式,软链接文件和原文件本质上不是同一个文件ln -s`` filename [linkname]
ln -s /data/dir /data/dirlink #绝对路径
cd /data #相对路径
ln -s ../data/dir /root/dirlink
rm -rf /data/dirlink #删除软链接本身,不会删除源目录内容
rm -rf /data/dirlink/ #删除源目录的文件,不会删除链接文件(注意!)
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 设备
[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:取字符集的补集
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
管道中的”-“符号
tee 重定向到多个目标
命令1 | tee [-a ] 文件名 | 命令2 …..:可以把命令1的STDOUT保存在文件中,做为命令2的输入(-a 追加)
功能:保存不同阶段的输出
复杂管道的故障排除
同时查看和记录输出
[root@centos8 ~]$ cat <<eof | tee /etc/motd
> zyy
> beautiful
> very
> eof
zyy
beautiful
very