对于计算机系统而言,管理存储的数据是一个非常重要的任务.为了方便管理,一般会用树形结构来整理文件.文件被包含在目录中,目录中又可以嵌套更小的目录.最终所有目录和文件都属于一个最大的根目录之下,把文件和目录之间的从属关系用图画出来就是一个树形的图.
不论是Linux还是Windows,像目录,文件这些概念都是经常用到的.我就不多赘述了.需要提醒只用过Windows用户的是Linux的目录是一个虚拟目录.而不是像Windows一样直接用磁盘分区当成了树形结构中的一个层级,最终的根目录("我的电脑")下一般只能看到若干个磁盘分区.
Linux通过"挂载",把计算机上所有的设备,文件和路径都整合到了一个树形结构之下.不管分了多少个区,装了多少块硬盘.始终只有一个根目录.从一个磁盘分区跳到另一个磁盘分区就像切换文件夹一样简单.而Windows下不同盘符的分区之间的距离还是要比文件夹之间的差距大很多的.
挂载和分区之类的问题我们后续还会讨论.现在只是提一下.
另外Linux中的一般原则是把任何东西看成文件.外接设备和目录也是特殊的文件而已.所以后续我提到"文件"的时候,有时候也包括目录.
现在来讨论如何描述一个文件树中的位置.由于树形结构的特点,我们依次列出从根到目标位置所经历的目录名(文件夹名),最后加上目标文件(或者文件夹)的名称就可以定位一个文件.
为了处理方便,一般不往表示路径的字符串中加入空格.不同层级的目录之间用'/'分割(Windows用'',和Linux又不一样).而最终的根目录是不需要名称的,所以就用一个单独的'/'来表示根目录.
而'/bin'这就表示根目录下的bin文件.'/usr/share'表示根目录下的usr目录下的share文件.
以上是绝对路径的表示方法.只要在同一个文件系统中,完全相同的绝对路径肯定表示同一个位置.
现在我们知道了Linux的文件系统中,所有的文件和文件夹组成了一个树形结构.但是还有很多东西没有确定.比如说,安装软件的时候安装到哪?man-db的帮助信息存放到哪?连接到计算机上的硬件抽象出来的文件应该放在哪?
Linux对此做了一系列的约定.大部分Linux发行版所遵循的约定是FHS(Filesystem Hierarchy Standard).
它约定了一个大致的树形结构,规定了那些目录放哪一类内容.这些约定在Linux的世界里是常识性的知识.详情可以去FHS的官网或者你用的Linux发行版的官网去查看.我这里列举一些常见的路径.
- /boot boot的本意是“靴子,猛踢”,引申为“启动”。这个文件夹中的文件主要和启动系统有关系。
- /etc 杂项和系统配置
- /srv 服务目录,存放本地服务相关文件
- /sys 系统目录,存放系统硬件信息相关文件
- /run 临时数据
- /tmp 临时文件目录
- /var 可变目录,用于存放日志等经常变化的文件
- /proc 并非实际存在的文件夹,用于监控系统
- /lib 部分核心库存放于此
- /lib64 部分核心库存放于此
- /bin 程序。系统运行所必须的程序。
- /sbin 系统二进制文件,通常为root用户预留
- /opt 安装可选软件
- /usr 普通用户程序(包括用户自行安装的程序、库、系统二进制文件以及一些日志文件和数据库等。)
- /home 用户主目录。每一个普通用户名在这个目录下有一个同名目录。
- /root root用户的主目录。(Ubuntu一开始没有设置root用户,所以这个文件夹为空。)
- /dev 设备结点
- /media 可移除媒体设备(CD-ROM等)
- /mnt 手动挂载的可移除设备
- /lost+found 除非发生重大系统崩溃,否则本文件夹为空。用于恢复崩溃后的文件。
如果想用树形图的方式查看文件路劲可以使用tree命令。这个命令不属于Coreutils,在用包管理软件安装的时候tree是一个独立的包。
一般的程序在启动时都有一个当前路径,表示程序默认的读写文件的路径.
比如bash启动后,默认当前路径为用户自己的home路径.此时通过bash创建或者搜索文件都会默认在这个路径下进行.
使用命令
pwd
来查看当前路径的绝对路径表示.
使用cd命令可以切换当前路径.最基础的用法是cd后加要切换到的绝对路径.
cd /usr/share
这会切换到/usr/share路径.
但是每次都输入绝对路径太麻烦,就好像开车的时候不用"前方五百米右转"来导航,而是告诉你目标经纬度位置.
于是就有了相对路径,相对路径的"相对"是指相对于当前路径.比如当前路径在/usr/share下,我输入
cd man
就表示跳转到当前路径下一个名叫man的路径下(如果存在的话).
相对路径都不能以'/'开头,防止和绝对路径混淆.但是相对路径也可以用很多层.例如当前我在/usr路径下,输入:
cd share/man
表示如果在当前下的share目录下有man目录则切换过去.
现在我们可以用cd逐级深入.如果cd的参数是'-'则会返回上次cd之前的路径(注意这本身也算一次cd).
cd -
现在要介绍的这个符号是相对路径和绝对路径通用的.无论何时,路径中出现'..'都表示上级目录.
在相对路径中直接使用表示当前目录的上级目录:
cd ..
如果是写在一串路径后边,则表示前边这一大串所表示的路径的上一层.例如
cd /usr/share/..
表示切换到/usr/share的上一级,也就是/usr.
它也可以连续使用
cd /usr/share/../..
这条命令其实就会切换到根目录.
有时候文件名会和命令名重名.这样就容易造成混淆.比如我当前路径下正好有一个叫help的可执行文件.如果输入help,bash应该是调用内置命令呢还是执行这个当前路径下的help可执行文件?
为了防止这种冲突,一般来说bash会优先考虑这个名称为命令名.如果要执行当前路径下的叫help的文件.需要显示指定.这会引入一个新的符号'.',单个的点.这个点表示当前路径.在名称不冲突的情况下'./help'和直接'help'只同一个文件.但是在名称冲突的情况下'./help'特指当前路径下的help文件.
由于bash的机制问题.如果你是要执行一个当前路径的可执行文件.而当前路径又不在系统变量PATH中,那么不管已有命令名和这个要执行的文件是否重名都必须使用显示指明的写法.
也就是说必须写成
./xxxx
直接写
xxxx
是不能启动xxxx的.
为了防止同一个计算机的多个用户相互干扰,Linux系统中一般会为不同用户设置不同的home路径.用户的home其实就是一个特定的文件夹.用户在自己的home一般可以为所欲为而不用担心干扰到别人的文件.
不带参数调用cd就会把当前路径切换到用户自己的home.
相对路径中还特别使用'~'来表示用户自己的home路径.
例如:
cd ~/Desktop
表示切换到自己的home下一个名为Desktop的路径下.
而在bash中启动程序的时候,bash的当前路径就是被启动的程序的当前路径.
这点可以通过在bash里启动bash或者python,lua来实验.
在Linux的约定下,一般来说如果路径末尾是一个文件夹名.则最后有没有'/'意思都一样.例如'/bin'和'/bin/'表示同一个位置.但是有的软件命令是默认支持BSD约定的.这种情况下末尾的'/'会造成命令意义不同(例如rsync命令).
这里介绍一个dirname命令.接受一个路径作为参数.它会返回路径所指的文件或者目录的上级目录.例如:
dirname /usr/bin/
这条命令返回/usr.
dirname /bin/bash
这条命令返回bin.
dirname ~
这条命令一般返回/home.
如果用/作为参数.则会返回/本身.
注意这只是字符串层面的解析,而不是查找真实的文件目录.写一个不存在的路径也能进行分析:
dirname /abc/def/hkj
相对路径也不能解析:
dirname ../../home/../good/../
与dirname相对的有一个basename命令用于解析路径所指的文件或者路径本身的名字.尝试:
basename /usr/bin/
basename /bin/bash
要验证字符串是不是一个合乎路径语法规范的路径使用命令pathchk.
要解析相对路径,使用命令realpath.