写点什么

Linux 一切皆文件,如果你没做到这一步,那这就是句话而已

用户头像
小Q
关注
发布于: 2020 年 11 月 12 日

前言


相信当你接触 Linux 的时候,身边的人就向你灌输一个概念,或者说你就总是听到一句话:Linux 系统中一切皆文件


Linux 下“一切皆文件”是 Unix/Linux 的基本哲学之一。不信,看下面这张图



普通文件、目录、字符设备、块设备和网络设备(套接字)等在 Unix/Linux 都被当做文件来对待。虽然他们的类型不同,但是 linux 系统为它们提供了一套统一的操作接口。


Linux 的一切皆文件是指,Linux 世界中的所有、任意、一切东西都可以通过文件的方式访问、管理。


反过来说,是 Linux 和 GNU 世界定的规范,任何东西都挂在文件系统之上,即使它们不是文件,也以文件的形式来呈现。


比如我们经常会讲的进程(/proc)、设备(/dev)、Socket 等等,实际上都不是文件,但是你可以以文件系统的规范来访问它,修改属主和属性。


那你对这句话的理解是不是仅仅止步于此呢?那我想,下面的这些内容你真的要看一下了


实际操作认证


Linux 下有 lsof 命令,可以查看所有已经打开的文件,你使用 lsof -p [pid]的方式就可以查看对应的进程都打开了什么文件,而其中的 type 字段就是表明它是什么类型,通过 man losf 命令你可以查看到它有下面这么多种。


TYPE       is the type of the node associated with the file - e.g., GDIR, GREG, VDIR, VREG, etc.
复制代码


      or ``IPv4'' for an IPv4 socket;
复制代码


      or ``IPv6'' for an open IPv6 network file - even if its address is IPv4, mapped  in  an IPv6 address;
复制代码


      or ``ax25'' for a Linux AX.25 socket;
复制代码


      or ``inet'' for an Internet domain socket;
复制代码


      or ``lla'' for a HP-UX link level access file;
复制代码


      or ``rte'' for an AF_ROUTE socket;
复制代码


      or ``sock'' for a socket of unknown domain;
复制代码


      or ``unix'' for a UNIX domain socket;
复制代码


      or ``x.25'' for an HP-UX x.25 socket;
复制代码


      or ``BLK'' for a block special file;
复制代码


      or ``CHR'' for a character special file;
复制代码


      or ``DEL'' for a Linux map file that has been deleted;
复制代码


      or ``DIR'' for a directory;
复制代码


      or ``DOOR'' for a VDOOR file;
复制代码


      or ``FIFO'' for a FIFO special file;
复制代码


      or ``KQUEUE'' for a BSD style kernel event queue file;
复制代码


      or ``LINK'' for a symbolic link file;
复制代码


      or ``MPB'' for a multiplexed block file;
复制代码


      or ``MPC'' for a multiplexed character file;
复制代码


      or  ``NOFD''  for a Linux /proc/<PID>/fd directory that can't be opened -- the directory      path appears in the NAME column, followed by an error message;
复制代码


      or ``PAS'' for a /proc/as file;
复制代码


      or ``PAXV'' for a /proc/auxv file;
复制代码


      or ``PCRE'' for a /proc/cred file;
复制代码


      or ``PCTL'' for a /proc control file;
复制代码


      or ``PCUR'' for the current /proc process;
复制代码


      or ``PCWD'' for a /proc current working directory;
复制代码


      or ``PDIR'' for a /proc directory;
复制代码


      or ``PETY'' for a /proc executable type (etype);
复制代码


      or ``PFD'' for a /proc file descriptor;
复制代码


      or ``PFDR'' for a /proc file descriptor directory;
复制代码


      or ``PFIL'' for an executable /proc file;
复制代码


      or ``PFPR'' for a /proc FP register set;
复制代码


      or ``PGD'' for a /proc/pagedata file;
复制代码


      or ``PGID'' for a /proc group notifier file;
复制代码


      or ``PIPE'' for pipes;
复制代码


      or ``PLC'' for a /proc/lwpctl file;
复制代码


      or ``PLDR'' for a /proc/lpw directory;
复制代码


      or ``PLDT'' for a /proc/ldt file;
复制代码


      or ``PLPI'' for a /proc/lpsinfo file;
复制代码


      or ``PLST'' for a /proc/lstatus file;
复制代码


      or ``PLU'' for a /proc/lusage file;
复制代码


      or ``PLWG'' for a /proc/gwindows file;
复制代码


      or ``PLWI'' for a /proc/lwpsinfo file;
复制代码


      or ``PLWS'' for a /proc/lwpstatus file;
复制代码


      or ``PLWU'' for a /proc/lwpusage file;
复制代码


      or ``PLWX'' for a /proc/xregs file;
复制代码


      or ``PMAP'' for a /proc map file (map);
复制代码


      or ``PMEM'' for a /proc memory image file;
复制代码


      or ``PNTF'' for a /proc process notifier file;
复制代码


      or ``POBJ'' for a /proc/object file;
复制代码


      or ``PODR'' for a /proc/object directory;
复制代码


      or ``POLP'' for an old format /proc light weight process file;
复制代码


      or ``POPF'' for an old format /proc PID file;
复制代码


      or ``POPG'' for an old format /proc page data file;
复制代码


      or ``PORT'' for a SYSV named pipe;
复制代码


      or ``PREG'' for a /proc register file;
复制代码


      or ``PRMP'' for a /proc/rmap file;
复制代码


      or ``PRTD'' for a /proc root directory;
复制代码


      or ``PSGA'' for a /proc/sigact file;
复制代码


      or ``PSIN'' for a /proc/psinfo file;
复制代码


      or ``PSTA'' for a /proc status file;
复制代码


      or ``PSXSEM'' for a POSIX semaphore file;
复制代码


      or ``PSXSHM'' for a POSIX shared memory file;
复制代码


      or ``PTS'' for a /dev/pts file;
复制代码


      or ``PUSG'' for a /proc/usage file;
复制代码


      or ``PW'' for a /proc/watch file;
复制代码


      or ``PXMP'' for a /proc/xmap file;
复制代码


      or ``REG'' for a regular file;
复制代码


      or ``SMT'' for a shared memory transport file;
复制代码


      or ``STSO'' for a stream socket;
复制代码


      or ``UNNM'' for an unnamed type file;
复制代码


      or ``XNAM'' for an OpenServer Xenix special file of unknown type;
复制代码


      or ``XSEM'' for an OpenServer Xenix semaphore file;
复制代码


      or ``XSD'' for an OpenServer Xenix shared data file;
复制代码


      or the four type number octets if the corresponding name isn't known.
复制代码


这里我也添加一些实例给大家更好地展示一下



# 进到proc目录
复制代码


[root@k8s ~]# cd /proc
复制代码


[root@k8s proc]# ls
复制代码


1     1063  1077  11    12    1504  19    2175  24   280  297  301  317  39   407  413  49   519  726  737        bus       devices      filesystems  kallsyms    kpageflags  modules       partitions   softirqs       timer_list   vmstat
复制代码


10    1066  1078  1100  13    16    2     2176  25   281  298  302  36   391  408  414  495  52   729  743        cgroups   diskstats    fs           kcore       loadavg     mounts        sched_debug  stat           timer_stats  zoneinfo
复制代码


102   1068  1083  1102  14    1746  20    2177  26   282  299  303  37   392  409  415  5    53   733  8          cmdline   dma          interrupts   keys        locks       mpt           schedstat    swaps          tty
复制代码


1038  1071  1085  1110  15    1748  2005  2178  27   29   3    304  38   4    410  416  50   6    734  9          consoles  driver       iomem        key-users   mdstat      mtrr          scsi         sys            uptime
复制代码


1061  1072  1097  1113  1502  1749  2007  22    279  294  30   305  380  405  411  47   51   66   735  acpi       cpuinfo   execdomains  ioports      kmsg        meminfo     net           self         sysrq-trigger  version
复制代码


1062  1073  1099  1164  1503  18    21    23    28   296  300  31   381  406  412  48   511  7    736  buddyinfo  crypto    fb           irq          kpagecount  misc        pagetypeinfo  slabinfo     sysvipc        vmallocinfo
复制代码


复制代码


# 可以看到上面有很多以数字为名称的目录,而这些目录就对应每一个进程
复制代码


# 使用ps -ef|grep nginx可以找到Nginx主进程的PID是2175
复制代码


[root@k8s proc]# ps -ef|grep nginx
复制代码


root       2175      1  0 10:23 ?        00:00:00 nginx: master process /usr/sbin/nginx
复制代码


nginx      2176   2175  0 10:23 ?        00:00:00 nginx: worker process
复制代码


nginx      2177   2175  0 10:23 ?        00:00:00 nginx: worker process
复制代码


root       2182   2007  0 10:24 pts/0    00:00:00 grep --color=auto nginx
复制代码


复制代码


# 进入/proc/2175目录,可以看到这个进程相关的目录
复制代码


[root@k8s 2175]# ls
复制代码


attr       cgroup      comm             cwd      fd       io        map_files  mountinfo   net        oom_adj        pagemap      projid_map  schedstat  smaps  statm    task     wchan
复制代码


autogroup  clear_refs  coredump_filter  environ  fdinfo   limits    maps       mounts      ns         oom_score      patch_state  root        sessionid  stack  status   timers
复制代码


auxv       cmdline     cpuset           exe      gid_map  loginuid  mem        mountstats  numa_maps  oom_score_adj  personality  sched       setgroups  stat   syscall  uid_map
复制代码


# 这里面的内容就是2175进程的全部内容了,非常多的命令实际上都是从这个目录读取的信息,比如上面的ps命令
复制代码


复制代码


# 上面的文件我举几个例子解释一下
复制代码


# 1. fd目录,里面是此进程打开的文件的情况,每个均链接至实际的文件或设备
复制代码


[root@k8s 2175]# ll fd
复制代码


总用量 0
复制代码


lrwx------ 1 root root 64 9月  29 10:53 0 -> /dev/null
复制代码


lrwx------ 1 root root 64 9月  29 10:53 1 -> /dev/null
复制代码


lrwx------ 1 root root 64 9月  29 10:53 10 -> socket:[26530]
复制代码


l-wx------ 1 root root 64 9月  29 10:53 2 -> /var/log/nginx/error.log
复制代码


lrwx------ 1 root root 64 9月  29 10:53 3 -> socket:[26527]
复制代码


l-wx------ 1 root root 64 9月  29 10:53 4 -> /var/log/nginx/error.log
复制代码


l-wx------ 1 root root 64 9月  29 10:53 5 -> /var/log/nginx/access.log
复制代码


lrwx------ 1 root root 64 9月  29 10:53 6 -> socket:[27700]
复制代码


lrwx------ 1 root root 64 9月  29 10:53 7 -> socket:[27701]
复制代码


lrwx------ 1 root root 64 9月  29 10:53 8 -> socket:[26528]
复制代码


lrwx------ 1 root root 64 9月  29 10:53 9 -> socket:[26529]
复制代码


复制代码


# 2. limits,内容是此进程的系统限制信息
复制代码


[root@k8s 2175]# cat limits
复制代码


Limit                     Soft Limit           Hard Limit           Units
复制代码


Max cpu time              unlimited            unlimited            seconds
复制代码


Max file size             unlimited            unlimited            bytes
复制代码


Max data size             unlimited            unlimited            bytes
复制代码


Max stack size            8388608              unlimited            bytes
复制代码


Max core file size        0                    unlimited            bytes
复制代码


Max resident set          unlimited            unlimited            bytes
复制代码


Max processes             14889                14889                processes
复制代码


Max open files            1024                 4096                 files
复制代码


Max locked memory         65536                65536                bytes
复制代码


Max address space         unlimited            unlimited            bytes
复制代码


Max file locks            unlimited            unlimited            locks
复制代码


Max pending signals       14889                14889                signals
复制代码


Max msgqueue size         819200               819200               bytes
复制代码


Max nice priority         0                    0
复制代码


Max realtime priority     0                    0
复制代码


Max realtime timeout      unlimited            unlimited            us
复制代码


复制代码


# 3. stack,此进程的内核调用栈信息
复制代码


[root@k8s 2175]# cat stack
复制代码


[<ffffffff958b5859>] sigsuspend+0x39/0x70
复制代码


[<ffffffff958b58ee>] SyS_rt_sigsuspend+0x5e/0x80
复制代码


[<ffffffff95f92ed2>] system_call_fastpath+0x25/0x2a
复制代码


[<ffffffffffffffff>] 0xffffffffffffffff
复制代码


复制代码


# 这些内容都不是普通的文件,你通过文件系统看,它们的大小都是0,但你看我能输出上面的这么多信息
复制代码


[root@k8s 2175]# ll
复制代码


总用量 0
复制代码


dr-xr-xr-x 2 root root 0 9月  29 10:25 attr
复制代码


-rw-r--r-- 1 root root 0 9月  29 10:25 autogroup
复制代码


-r-------- 1 root root 0 9月  29 10:25 auxv
复制代码


-r--r--r-- 1 root root 0 9月  29 10:23 cgroup
复制代码


--w------- 1 root root 0 9月  29 10:25 clear_refs
复制代码


-r--r--r-- 1 root root 0 9月  29 10:24 cmdline
复制代码


-rw-r--r-- 1 root root 0 9月  29 10:25 comm
复制代码


-rw-r--r-- 1 root root 0 9月  29 10:25 coredump_filter
复制代码


-r--r--r-- 1 root root 0 9月  29 10:25 cpuset
复制代码


...
复制代码


[root@k8s 2175]# du -sh
复制代码


0
复制代码

另外,我们经常会使用到的/dev/null, /dev/random,都是可以在文件目录中看到,但它们都不是普通的文件,而是 Linux Kernel 为了实现某些功能,同时存在 everything is a file 的约定,才把它们体现在了文件系统上。


另外补一个我觉得挺有用的,且应该不少人不知道的一个小技巧


man 5 proc 命令会输出/proc 目录的帮助信息,它里面包含/proc/[pid]目录中每个目录和文件的说明信息


PROC(5)                                                                                                                 Linux Programmer's Manual                                                                                                                 PROC(5)
复制代码


复制代码


NAME
复制代码


       proc - process information pseudo-file system
复制代码


复制代码


DESCRIPTION
复制代码


       The proc file system is a pseudo-file system which is used as an interface to kernel data structures.  It is commonly mounted at /proc.  Most of it is read-only, but some files allow kernel variables to be changed.
复制代码


复制代码


       The following outline gives a quick tour through the /proc hierarchy.
复制代码


复制代码


       /proc/[pid]
复制代码


              There is a numerical subdirectory for each running process; the subdirectory is named by the process ID.  Each such subdirectory contains the following pseudo-files and directories.
复制代码


复制代码


       /proc/[pid]/auxv (since 2.6.0-test7)
复制代码


              This contains the contents of the ELF interpreter information passed to the process at exec time.  The format is one unsigned long ID plus one unsigned long value for each entry.  The last entry contains two zeros.
复制代码


复制代码


       /proc/[pid]/cgroup (since Linux 2.6.24)
复制代码


              This file describes control groups to which the process/task belongs.  For each cgroup hierarchy there is one entry containing colon-separated fields of the form:
复制代码


复制代码


                  5:cpuacct,cpu,cpuset:/daemons
复制代码


复制代码


              The colon-separated fields are, from left to right:
复制代码


复制代码


                  1. hierarchy ID number
复制代码


复制代码


                  2. set of subsystems bound to the hierarchy
复制代码


复制代码


                  3. control group in the hierarchy to which the process belongs
复制代码


复制代码


              This file is present only if the CONFIG_CGROUPS kernel configuration option is enabled.
复制代码


复制代码


       /proc/[pid]/cmdline
复制代码


              This  holds  the complete command line for the process, unless the process is a zombie.  In the latter case, there is nothing in this file: that is, a read on this file will return 0 characters.  The command-line arguments appear in this file as a set
复制代码


              of strings separated by null bytes ('\0'), with a further null byte after the last string.
复制代码


复制代码


       /proc/[pid]/coredump_filter (since kernel 2.6.23)
复制代码


              See core(5).
复制代码


复制代码


       /proc/[pid]/cpuset (since kernel 2.6.12)
复制代码


              See cpuset(7).
复制代码


复制代码


       /proc/[pid]/cwd
复制代码


              This is a symbolic link to the current working directory of the process.  To find out the current working directory of process 20, for instance, you can do this:
复制代码


复制代码


                  $ cd /proc/20/cwd; /bin/pwd
复制代码


复制代码


              Note that the pwd command is often a shell built-in, and might not work properly.  In bash(1), you may use pwd -P.
复制代码


复制代码


              In a multithreaded process, the contents of this symbolic link are not available if the main thread has already terminated (typically by calling pthread_exit(3)).
复制代码


其实,这就是 Linux 最让人着迷的地方,总是感觉很多东西都很简单,一个命令行就可以解决问题,但是深入去研究一下,你又会发现,真的有很多更神秘的地方再等待着你去探索,越深入学习越觉得兴奋,起码我个人是这样觉得


加油吧,程序员


文章首发公众号:Java 架构师联盟,每日更新技术好文


发布于: 2020 年 11 月 12 日阅读数: 445
用户头像

小Q

关注

还未添加个人签名 2020.06.30 加入

小Q 公众号:Java架构师联盟 作者多年从事一线互联网Java开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果能为您提供帮助,请给予支持(关注、点赞、分享)!

评论

发布
暂无评论
Linux一切皆文件,如果你没做到这一步,那这就是句话而已