文件管理初探(inode理解)及管道和IO重定向

第一部分    文件管理初探

  1、Linux系统上各主要目录的简介

     

    /  根,所有文件的起点

    ├── bin    存放普通用户可执行的相关二进制程序文件的目录,不能单独分区,操作系统启动时会用到该目录下的相关程序

    ├── boot    存放操作系统启动时的引导程序,以及操作系统内核文件

    ├── dev    存放设备文件和特殊文件(如字符设备)

    ├── etc    存放配置文件的目录

    ├── home    普通用户的家目录默认都在此目录下

    ├── lib    存放系统库和内核模块文件(/lib/modules)

    ├── lib64    存放x86_64位系统上共享库文件

    ├── media    系统上提供的设备挂载点

    ├── misc    系统上提供的设备挂载点

    ├── mnt    系统上提供的设备挂载点

    ├── opt    第三方应用程序的安装位置

    ├── proc    用于输出内核与进程信息相关的虚拟文件系统

    ├── root    root用户的家目录

    ├── sbin    存放管理员用户可执行的相关二进制程序文件的目录,不能单独分区,操作系统启动时会用到该目录下的相关程序

    ├── selinux    selinux相关的安全策略等信息的存储位置

    ├── srv    系统上运行的服务用到的数据

    ├── sys    用于输出系统上硬件设备相关信息的虚拟文件系统

    ├── tmp    临时文件存储位置

    ├── usr    第三方软件的安装目录,该目录下有另一套完整的目录文件结构,包括有bin、sbin、local、include而local又有bin、sbin等

    └── var    保存经常容易变化的数据,如日志、httpd的网页文件、邮件等相关内容

  2、inode的认识总结

    

    个人总结的关于文件系统inode的一些原理: 

        文件系统在组织文件存储时,遵循一定的存储规则。在文件系统创建时,会将底层存储设备(硬盘)逻辑划分为一个一个的磁盘(block),一般一个block大小默认为4096个字节,也就是4K,这个值在ext系列文件系统上支持1024、2048、4096,可以在创建文件系统的时候指定(利用mke2fs -b SIZE来指定block大小,一旦指定后,后期不能更改),然后将多个磁盘块划分为一个个的块组,一个分区里面有有多个块组,但一个分区里面会有一部分block用来存储整个分区的一些属性状态的超级块,(用tune2fs -l DEVICE可以查看到分区超级块里面存储的信息,如分区卷标、分区的特性、挂载时的默认选项、总共有多少inode、总共多少block、每个块组有多少block、每个块组有多少inode等信息)。

        linxu上文件有两部分组成,一个是文件的元数据,一个是文件的数据本身,两部分分开存储,文件系统划分出来的磁盘块有部分用来存储inode table,有部分用来存储数据本身,文件的数据至少占据1个block大小,即使数据只有1byte,如果blick大小为4K,那么该文件数据占用的磁盘空间也是4K。inode table里面存储每每个文件的inode条目,每个条目在在同一个文件系统内部有一个唯一的ID号,一个inode条目记录一个文件的元数据信息,这些信息包括:该文件的权限、属主属组、大小、时间戳(但是inode条目里面是没有存储该文件的文件名的,这点要注意,文件名是存储在目录文件的数据块中)。

        inode条目还存储了该文件的数据所在的block的指针信息,也就是该文件数据存在哪个磁盘块上,一般一个inode条目的指针部分,分为直接指针、间接指针、二重指针、三重指针…直接指针在ext系列文件系统上有12个,一个直接指针指向一个磁盘块,故利用直接指针可以存储的数据大小,为4K*12。当数据超过48K时,就需要利用间接指针指向的数据区域来存储了,所谓间接指针就是inode的数据块指针指向了一个block块,但这个block本身存储的不是文件数据本身,而是存储的指针信息(在ext文件系统上,一个指针信息占用4字节的空间,故一个block可以有1024个指针信息),然后,由这个block块里面的指针指向具体文件数据存储磁盘块,这样,利用间接指针可以存储的文件大小为1024*4K。要存储的文件超过了间接指针能指向的范围,则需要用到二重指针,二重指针是指,inode条目里面的指针指向一个block,该block存储的依然是指针信息,一个指针指向一个block,而被指向的这个block存储的依然是指针信息,具体是这样:inode条目–>block(存的是指针)–>block(存的是指针)–>block(存的是文件数据),这样二重指针所能存储的文件数据大小就是1024*1024*4K,以此类推。

     直接指针:inode条目–>block(存的是文件数据)

     间接指针:inode条目–>block(存的是指针)–>block(存的是文件数据)

     二重指针:inode条目–>block(存的是指针)–>block(存的是指针)–>block(存的是文件数据)

     三重指针:inode条目–>block(存的是指针)–>block(存的是指针)–>block(存的是指针)–>block(存的是文件数据)

     利用直接指针能存储的文件大小:12*4K

     利用间接指针能存储的文件大小:1*1024*4K (一个inode条目只有1个间接指针)

     利用二重指针能存储的文件大小:1*1024*1024*4K

     利用三重指针能存储的文件大小:1*1024*1024*1024*4K

    

        而对于文件和目录的存储,在文件系统存储时是不一样的,文件存储中,数据部分存的是文件本身的数据文件,而目录文件,数据部分存储的是目录下面文件名与该文件的inode号的对应关系

        故当我们访问某个文件时,文件系统内部寻找的过程大致是这样的:(以寻找/etc/issue为例)

            首先找/根,因为根是自启动的,可以知道自己是在哪个inode上,找到/的inode后,inode指向了/下相应的数据存储的block,该block内部存储了/下一级子目录的名称和inode对应关系(当然如果/下有直接的文件,那某些数据块上存储的就是文件的数据),通过对应关系,就找到了etc所在的inode,然后通过etc的indode,就找到了etc下面的文件和目录的数据存储的block,进而找到了issue文件的数据

        inode.png

  3、文件类型和软硬链接的介绍

     ls -l 中查看到的权限字段的信息中第一位即表示该文件的类型,常见的文件类型有:

        –    表示普通文件

        d    表示目录文件

        b    表示块设备文件,如硬盘

        c    表示字符设备文件,如/dev/zero、/dev/null、/dev/ramdom

        l    表示符号链接文件

        p    表示管道文件

        s    表示socket套接字文件

    

    硬链接:多个文件路径指向的是同一个innod,故通过innod找到的磁盘块也就是同样的

        特性:

        1、目录不支持硬链接

        2、硬链接不能跨文件系统

        3、创建硬链接会增加inode引用计数

        硬链接创建方式:ln 原文件  链接文件

    软链接:指向一个文件路径的另一个文件路径,符号链接文件本身的innod中存放磁盘块指针的位置,不是存的磁盘块指针,而是指向了另外一个路径

        特性:

        1、符号链接与文件时两个各自独立的文件,各有自己的inode;对原文件创建软链接,不会增加引用计数

        2、支持对目录创建符号链接,可以跨文件系统

        3、删除符号链接文件不影响原文件,但删除原文件,符号链接指定的路径即不存在,此时会变成无效的链接

        4、符号链接文件的大小,是其指向的文件的路径字符串的字节数

软链接创建方式:ln -s 原文件 链接文件

        注意:创建软链接时,原始文件的路径要使用绝对路径,如果要使用相对路径,则要相对于链接文件的路径,不能是相对于当前工作目录的相对路径

  

  4、文件系统相关命令

    cd:改变工作目录

        cd /PATH/TO/SOMEDIR  切换到指定目录

        cd  切换回家目录

        cd ~   切换回自己家目录

        cd ~USERNAME   切换到指定用户的家目录(只有管理员才有权限切换到其他用户的家目录)

        cd –    在上一次所在目录与当前目录之间来回切换

            PWD   用来记录当前工作目录的环境变量

            OLDPWD   用来记录上一次工作目录的环境变量

    ls:列出指定目录下的内容

        语法:ls [OPTION]…[FILE]…

        常用选项:

         -a 显示所有文件,包括隐藏文件

         -A  显示除.和..之外的所有文件

         -l  长格式列表,表示显示文件的详细属性信息

             显示出来的信息为

             -rw-r-x—  2  root  root  8827  10月15 20:34 testa.log

             -rw-r-x—该文件的文件类型和相应的权限

             2  表示文件被硬链接的次数

             root  表示文件的属主

             root  表示文件的属组

             8827  表示文件的大小

         但是如果对ll /dev 该处显示的是两个数字,类似brw-rw—-. 1 root cdrom    11, 0   7月13 00:34 sr0

         这里的数字前一个表示主设备号,后一个表示次设备号,前一个数字一样,表示设备类型一样,后一个数字表示该种设备下的不同的设备

             10月15 20:34 表示文件最后一次被修改的时间

         -h 表示对文件大小做单位换算,换算后的结果可能为非精确值(1000和1024的区别)

         -d 表示仅显示目录自身,而不是目录下面每个文件的属性,要与-l一起使用,显示目录自身的属性信息

         -r ,–reverse 表示显示时以逆序的方式进行显示,默认是升序显示

         -R ,–recursive 表示递归显示

         ls -ld 目录和符号链接信息

         ls -1 文件分行显示

         ls -S 按从大到小排序

         ls -u 配合-t,显示并按atime从新到旧排序

         ls -U不排序按目录存放顺序显示

         ls -i  可以显示文件的inode编号

    stat命令:显示文件或文件系统的状态,显示文件的元数据

         例如:stat /etc/passwd

         显示大小、innod号,权限、最近一次访问时间(atime)、最近一次的更改时间(mtime)(改变文件内容),最近一次的改变时间(ctime)(改变文件元数据);

    

    touch命令:改变文件的时间戳(atime、mtime、ctime)

     语法:touch [OPTION]…FILE…

     touch 以存在的文件,表示改变文件的三个时间戳

            touch 不存在的文件,表示新建该文件

     touch -a 已存在的文件  表示改变文件的访问时间atime

     touch -m 已存在的文件  表示改变文件的改变时间mtime

     -c  表示如果文件不存在,则不创建该文件

     -t 时间;表示修改为的时间

         例如:touch -m -t 201607211658.20 /tmp/nwc.txt

         表示修改/tmp/nwc.txt文件的修改时间为2016年07月21日16点58分20秒

    

    cp命令:文件复制命令

    从文件系统存储级别来理解cp:分配一个空闲的inode号,在inode表中生成一个新的条目,在目录中创建一个目录项,将名称与inode编号关联,拷贝数据,生成新的文件

     语法:

     单源复制:cp [OPTION]… [-T] SOURCE DEST

     多源复制:cp [OPTION]… SOURCE… DIRECTORY         

        单源复制:cp [OPTION]… [-T] SOURCE DEST

            如果DEST不存在,则事先创建此文件,并复制源文件的数据至DEST中;

            如果DEST存在:

                如果DEST是非目录文件,则覆盖目标文件

                如果DEST是目录文件,则事先在DEST目录下创建一个与源文件同名的文件,并复制其数据流

        多源复制:cp [OPTION]… SOURCE… DIRECTORY

            如果DEST不存在:错误

            如果DEST存在:

                如果DEST是常规文件:错误

                如果DEST是目录:分别复制每个文件至目标目录中,并保持原名

        常用选项:

            -i  覆盖之前提醒用户确认,默认cp就带此选项

            -f  强制覆盖目标文件

            -r,-R  递归复制目录及目录中的内容至目标目录

            -d  复制软链接文件本身,而不是指向的源文件

            -a  复制文件时保留文件的全部元数据信息,实现归档,可用作备份

            –preserv=LIST  指定复制时要保留那些属性信息

                mode:权限

                ownership:属主和属组

                timestamps:时间戳信息

                context:安全标签

                xattr:扩展属性

                links:符号链接

                all:上述所有属性

    mv命令:文件移动命令

    (注意:同一个分区的mv操作,只是改了对应目录文件数据中针对该文件的指针信息,文件自身的inode和数据块都没发生改变,但是不同分区之间的mv操作是全部都改掉的)

    从文件系统存储级别来理解mv:如果源和目标在同一个文件系统内部进行mv操作,则对应的操作相当于用新的文件名,创建对应新的目录项,删除旧的目录项及对应的旧的文件名,整个操作不会涉及到文件本身的inode号的改变和数据块的改变,只会修改inode条目上的时间戳信息,数据块的内容不会发生移动

        如果源和目标不在同一文件系统,则相当于cp和rm的操作

        语法:与cp一样

        常用选项 -i、-f

    rm命令:删除文件(建议自己建个目录文件,把要删除的文件先mv到此目录,过段时间后确认不用后,再删除)

    从文件系统存储级别来理解rm:链接数递减,取消inode与数据block之间的关联关系,释放inode号,将数据块标志为空闲状态,删除目录项。rm命令是不会删除数据块中的数据的,只是标记为空闲,让其他文件的数据可以写到该数据块,从而覆盖掉以前的数据

        常用选项:-i、-f、-r

    alias  可以显示当前系统上的命令别名信息

     定义命令别名:

         alias NAME='COMMAND'  只对当前shell有效,立即生效,重启后失效

         例如 alias cds=‘cd /etc/sysconfig/network-scripts/’

     撤销别名:

         umalias NAME

         例如 unalias cds

     要想永久生效,可定义在/etc/bashrc配置文件中,如果只想对某个用户永久有效,可以在该用户家目录中.bashrc中定义

    

    tree命令  显示目录树

         -d 只显示目录

         -L LEVEL  指定显示的层级数目

         -P PARTEREN  指定显示通配符的目录

    mkdir 创建目录

         -p  递归创建,存在于不报错,且可以自动创建所需的各目录

         -v 显示详细过程

         -m MODE  创建目录时指定权限

             mkdir -pv /testdir/dir1/{x,y}/{a,b}

             mkdir -pv /testdir/dir2/{x/{a,b},y}

             mkdir -pv /testdir/dir{3,4,5/dir{6,7}}

    rmdir  删除空目录

         -p  递归删除父空目录

         -v 显示详细信息

    file命令

        语法file [OPTION] FILENAME

        选项:

          -b  显示时不显示文件名

          -f FILE  将需要判断文件类型的文件写到一个文件中,用-f指定这个文件,批量判断文件类型

          -F  显示时用指定的符号作为分隔符,默认是:冒号

          -i  显示出文件的编码类型

          -L  判断软链接时,默认只显示软链接文件本身的类型,不显示原文件的类型,加上-L后,可以显示出源文件的类型

  5、通配符

    *  匹配零个或多个任意字符

    ? 匹配任意单个字符

    ~  当前用户家目录

    ~USERNAME  指定用户家目录

    ~+ 当前工作目录

    ~- 前一个工作目录

    [0-9] 匹配一个数字范围

    [a-z] 大写和小写字母,表示aAbBcC…yYz  不包含大Z

    [A-Z] 大写和小写字母,表示AbBcC…yYzZ  不包含小a

        例如:[a-d]表示匹配 aAbBcCd 不包含大D

            但[abcd]则只匹配abcd

    [nwc9] 匹配括号内的单个字符

    [^nwc9] 匹配除括号内的字符意外的任意单个字符

    [[:digit:]] 匹配任意数字,相当于[0-9]

    [^[:digit:]] 匹配除数字之外的字符

    [[:lower:]] 匹配任意小写字母

    [[:upper:]] 匹配任意大写字母

    [[:alpha:]] 匹配任意大小字母

    [[:alnum:]] 匹配任意数字或大小写字母

    [[:space:]] 匹配空格

    [[:punct:]] 匹配标点

第二部分    管道和IO重定向

  1、标准输入输出介绍

    linux为程序提供三种I/O设备:

        标准输入(STDIN):0    默认是键盘

        标准输出(STDOUT):1    默认是终端窗口屏幕

        标准错误输出(STDERR):2    默认是终端窗口屏幕

  2、IO重定向

    I/O重定向就是将默认标准的输入、输出、错误输出定向的别的地方

    重定向的方法:命令  重定向操作符  重定向的目标

        >    标准输出重定向,覆盖目标的内容

        >>    标准输出重定向,将结果追加到目标,不会覆盖目标的内容

        2>    标准错误输出重定向,覆盖目标的内容

        2>>    标准错误输出重定向,将结果追加到目标,不会覆盖目标的内容

        &>    标准输出和标准错误输出重定向,覆盖目标的内容

        &>>    标准输出和标准错误输出重定向,将结果追加到目标,不会覆盖目标的内容

        多个命令合并的输出:

            例如:(cal 2015;cal2016)>/testdir/cal.txt

        <     输入重定向

            例如:mail -s “help” root</etc/issue

                tr ‘a-z’ ‘A-Z’</etc/issue

     tr命令:转换和删除字符

        语法:tr [OPTION]… ‘SET1’ [‘SET2’]

        选项:

            -c  取字符集的补集

            -s  把连续重复的字符,以单个字符表示

                tr -s‘\n’ 表示把连续的换行符,变成1个换行符,可实现删除空白行

            -d  删除SET1匹配到的内容

            -t  将SET1的内容转换成SET2的内容

        SET支持的内容格式:

          \NNN 八进制值为NNN 的字符(1 至3 个数位)

          \\ 反斜杠

          \a 终端鸣响

          \b 退格

          \f 换页

          \n 换行

          \r 回车

          \t 水平制表符

          \v 垂直制表符

          字符1-字符2 从字符1 到字符2 的升序递增过程中经历的所有字符

          [字符*] 在SET2 中适用,指定字符会被连续复制直到吻合设置1 的长度

          [字符*次数] 对字符执行指定次数的复制,若次数以 0 开头则被视为八进制数

          [:alnum:] 所有的字母和数字

          [:alpha:] 所有的字母

          [:blank:] 所有呈水平排列的空白字符

          [:cntrl:] 所有的控制字符

          [:digit:] 所有的数字

          [:graph:] 所有的可打印字符,不包括空格

          [:lower:] 所有的小写字母

          [:print:] 所有的可打印字符,包括空格

          [:punct:] 所有的标点字符

          [:space:] 所有呈水平或垂直排列的空白字符

          [:upper:] 所有的大写字母

          [:xdigit:] 所有的十六进制数

          [=字符=] 所有和指定字符相等的字符

   

  3、管道

    管道(|)用来连接命令,例如:

    COMMAND1|COMMAND|COMMAND3…

    表示将COMMAND1的输出作为COMMAND2的输入,COMMAND的标准输出作为COMMAND3的输入

    注意:错误输出默认不能通过管道进行发送,如果要发送,可以利用2>&1或|&来实现

第三部分    练习

  1、将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中

    tr 'a-z' 'A-Z' < /etc/issue >/tmp/issue.out

  2、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中

    who|tr 'a-z' 'A-Z' >/tmp/who.out

  3、一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:

      Hello, I am 用户名,the system version is here,pleasehelp me to check it ,thanks!

     操作系统版本信息

      echo -e "hello,I am `whoami`,The system version is ,please help me to check it,thanks\n`uname -sr`" |mail -s "help" root

  4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开

      for i in `ls /root`;do echo -n "$i ";done;echo

  5、file1文件的内容为:”1 2 3 4 5 6 7 8 9 10” 计算出所有数字的总和

       i=$((`tr ' ' '+' </testdir/file1`));echo $i

  6、删除Windows文本文件中的'^M'字符

      cat -A /testdir/新建文本文档.txt | tr -d '^M'

  7、处理字符串“xt.,l 1 jr#!$mn2 c*/fe3 uz4”,只保留其中的数字和空格

      echo 'xt.,l 1 jr#!$mn2 c*/fe3 uz4'|tr -d '[:alpha:][:punct:]'

  8、将PATH变量每个目录显示在独立的一行

      echo $PATH|tr ':' '\n'

  9、删除指定文件的空行

      tr -s '\n' '\n' </testdir/f1

  10、将文件中每个单词(字母)显示在独立的一行,并无空行

      tr -s '\n' '\n' <f1|tr ' ' '\n'

原创文章,作者:M20-1倪文超,如若转载,请注明出处:http://www.178linux.com/26505

(1)
M20-1倪文超M20-1倪文超
上一篇 2016-07-29
下一篇 2016-07-29

相关推荐

  • 变量

    变量     在shell脚本中,单独的字符或者命令只能引用一次,对于变量,我们可以多次引用,且对变量的赋值修改方便。对于一条很长的命令或者频繁使用的路径等,我们可以赋值给一个变量,比如获得系统中所有用户的uid,要输入很长的一段命令,我们如果每次使用都输入命令是件很麻烦的事情,如果赋值变量,那么就会很方便。设置变量userui…

    Linux干货 2017-08-06
  • Linux 基础(6)—— 权限

    修改所属人,所属组                文件的 r w x 权限            修改文件的权限chmod          umask &nb…

    2017-07-27
  • 马哥教育21期网络班—第三周课程+练习

    1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。 who |cut -d" " -f1 |sort -u 2、取出最后登录到当前系统的用户的相关信息。 id `who | tail -n …

    Linux干货 2016-07-12
  • 让运维工程师不再蓝瘦、香菇

    最近广西一小哥失恋后录的视频风靡互联网,也让“蓝瘦、香菇”这两个词火了一把。虽然原故事男主角是因为失恋才蓝瘦、香菇,但想想作为运维“狗”的我们也时常因强大的工作压力而蓝瘦,常常在晚上睡得香呼呼的时候因为要处理故障从温暖的被窝爬起来,看着铝朋友鄙视的眼神,真的好香菇……本来作为技术大牛的我们,工作应该是很酷的事情,享受的应该是小白美铝们崇拜的眼神,可现在却那么…

    系统运维 2017-01-09
  • Javascript 装载和执行

    一两个月前在淘宝内网里看到一个优化Javascript代码的竞赛,发现有不少的人对Javascript的执行和装载的基础并不懂,所以,从那天起我就想写一篇文章,但一直耽搁了。自上篇《浏览器渲染原理简介》,正好也可以承前启后。 首先,我想说一下Javascript的装载和执行。通常来说,浏览器对于Javascript的运行有两大特性:1)载入后马上执行,2)执…

    Linux干货 2016-07-10
  • Linux上命令使用格式及如何获取帮助信息

    Linux系统上命令使用: 命令本身是一个可执行的程序文件,二进制格式的文件,有可能会调用共享库文件,发起一条命令,请求内核将某一个二进制程序运行为一个进程。   命令的语法格式:   ~]#COMMAND(命令)   OPENTIONS(选项)   ARGUMENTS(参数) command 命令…

    Linux干货 2016-10-30