跳转至

文件路径和当前工作目录

引言

上一章我们学习了一部分操作文件系统的shell命令.在学习过程我们不止一次遇到这样的问题,如何表示一个文件或文件夹在文件系统的位置?同时,我们在上一章中提到,linux的文件系统被组织成一个类似树状的结构。因此,很自然地,我们想到可以使用从根节点开始的一个路径表示文件系统中的一个位置。这就是文件路径。另外,shell为了表示目前我们在文件夹中的位置,引入了当前工作目录这个概念。

文件路径

绝对路径

因为linux文件系统一定是一棵树,所以linux文件系统一定只有一个根。这个根节点是一个特殊的目录,它是linux文件系统的源头,一般被我们称为根目录,使用符号/表示。

从根目录开始,进入一系列文件夹之后,一定可以到达我们的目标文件或者文件夹。把这个路径上经过的所有文件夹的名称,和目标本身的名称按顺序记录下来,就形成了linux系统下文件的绝对路径。linux系统使用/作为路径上每个名称的分隔符。这个记号和根目录是同一个符号,但是含义完全不同。如果你的目标是一个文件夹,那么结尾有没有/都可以。但是在有些时候,结尾加上/可以暗示你这个目标是一个文件夹而不是一个文件。

使用文件的绝对路径已经可以表示linux文件系统所有的文件和文件夹的位置了。你现在可以使用lscd命令探索一下linux的文件系统了。

注意:如果你现在拥有root权限(也就是linux系统的最高权限),那么请你在探索linux的文件系统的时候不要随意修改那些你不知道作用的文件和文件夹。可以用命令行提示符中显示的用户名来判断,如果你的用户名是root,那么你拥有root权限。

相对路径

在你进行探索的时候,可能会发现,总是使用绝对路径相当不方便。例如:现在我的根目录下有一个叫做tmp的文件夹,它的绝对路径是/tmp。我进入这个文件夹我需要使用

cd /tmp
还可以,对吗?进入文件夹之后使用ls发现tmp文件夹下面有一个叫做kissshot的文件夹。我对这文件夹感兴趣,我现在进入这个文件夹需要使用
cd /tmp/kissshot
还行,可以接受。这个文件夹下面又有一个叫做acerolaorion的文件夹,我对这个文件夹感兴趣,决定进入这个文件夹。我需要使用
cd /tmp/kissshot/acerolaorion
嗯,稍微有点长了。这个文件夹下面又有一个叫做heartunderblade的文件夹,现在想要进入这个文件夹要使用什么命令呢?
cd /tmp/kissshot/acerolaorion/heartunderblade
是不是感觉有点开始红温了呢?

总是使用绝对路径实在是太繁琐太麻烦了,在刚才那个例子中,相同的路径部分被重复写了很多遍。作为学习计算机的同学,我们应该有这样的想法,当一件事需要反复做很多遍的时候,我们就应当尝试使用计算机和程序来解决这个问题。

因此linux系统提供了相对路径的概念。相对路径相当于是从当前你所在的位置开始,沿着树到达目标的路径,当你的位置和目标距离比较近的时候,这个路径可能会比从根节点开始更短。另外,如果你在一个文件夹的内部使用相对路径,当这个文件夹整体在文件系统中的位置发生变化的时候,这个相对路径是不会发生变化的,也就是相对路径仍然可以用。

为了表示相对路径,我们需要额外拥有两种能力,一个是表示当前文件夹的能力,一个是在树状结构中表示上一层的能力。这两个在linux文件系统的相对路径中分别表示为...,其中.表示当前文件夹,..表示上一级文件夹。这两个记号既可以看做是路径中的特殊符号,从上一章ls -a的结果中也能看到,它们也可以被看做是每个文件夹都拥有的两个特殊的文件夹(硬链接)。

因为相对路径是从当前所在位置开始的路径,因此和绝对路径不同,相对路径的起点总是.,也就是相对路径总是./开头的。继续用上面我的那个例子,现在我所在的位置是/tmp/kissshot/acerolaorion,我现在想要进入tmp/kissshot/acerolaorion/heartunderblade。如果使用相对路径的话,命令是这样的

cd ./heartunderblade
也就是我要进入的文件夹是当前文件夹下的heartunderblade文件夹,这里的.表示当前文件夹,/是文件夹之间的间隔符。

那么如果我要从/tmp/kissshot/acerolaorion进入/tmp/kissshot/42呢?可以使用这个这个命令

cd ./../42
也就是进入当前文件夹的上一级文件夹下的42这个文件夹。

但是即使是这样,人们还是觉得路径有一些冗余,因为相对路径使用的太频繁了,所以每次都以./开头还是让人觉得有点麻烦。因此我们可以省略./,linux文件系统会默认我们使用的相对路径,除非我们的路径是以/或者~开头的。(~是什么后面马上会讲到)

也就是上面的两条指令分别可以省略为

cd heartunderblade
cd ../42

最后,我们有这样一个问题,如果想要从/tmp/kissshot/acerolaorion/heartunderblade回到/tmp,使用相对路径应该怎么做呢?其实很简单,我相信大家应该都能想到

cd ../../..
看上去有些奇怪,但是没问题。

文件系统中一个特殊的位置——主目录(home)

在这一章的最开始,我们已经介绍了一个文件系统中的特殊位置,根目录(/)。现在我们要介绍linux文件系统中的另一个特殊位置,主目录。linux系统上,每个用户都有一个自己的主目录,如果你是root用户,那么主目录的路径是/root,如果你是其他用户并且你的文件名是xxx,那么主目录的路径是/home/xxx。在linux系统下,所有用户数据都应该放在这个用户的主目录下,这样可以保证不同用户的数据之间不会互相干扰。

许多软件软件的配置文件都存在于用户的主目录中,它们通常都是隐藏文件。例如:上一章在使用ls -a的时候,文件夹下面可能还出现了名为.bashrc的文件,这是bash的配置文件。这样不同用户对同一个软件可以拥有不同的配置。

因为主目录的特殊地位,所以主目录也可以作为相对路径的起点,使用~表示。这是linux系统的文件路径中的一个特殊记号。

需要注意的是,~...不完全相同。~并不是不是一个文件,它是一个特殊记号,这个记号在shell解析命令行参数的时候就会被展开。你可以尝试输入一下命令。

echo ~
根据我们所学的echo的功能,这条命令应该输出~这个符号才对。但是我们发现,echo却输出了我们自己的主目录的绝对路径。这就是因为~这个符号被bash展开成主目录的绝对路径之后才被当做参数传入echo的。

bash的展开是一个有点复杂但是很有用的功能,具体内容会在第20章中讲解。这里我们只要知道,有的时候一些特殊的符号或者符号组合会在shell中被替换成另外的东西。如果一个命令的运行结果出乎你的意料,可能要考虑你的参数中是否有特殊符号被展开了。通常避免展开的方式就是使用引号把你的参数包裹起来,就像我们对待参数中出现空格的时候做的那样。

最后,bash(其他shell应该也差不多),还提供一个关于主目录的展开,~xxx如果xxx是一个有效的用户名,那么这个东西会被展开成xxx这个用户的主目录绝对路径。

文件路径自动补全

一般比较现代的shell都会提供命令自动补全的功能,主要会进行的自动补全的就是文件路径。因为文件路径很有可能会很长,并且文件路径更有可能被预测。bash提供了最近的文件路径补全,输入路径的前一部分,然后按Tab键就会自动补全。自动补全的结果有下面几种可能性。

  1. 如果只有一条路径和你输入的部分开头相同,那么自动补全会将路径完整补全。

  2. 如果没有一条可能路径和你输入的部分开头相同,那么自动补全不会进行并且会给你播放\a(振铃符)的声音。

  3. 如果有大于一条可能的路径和你输入的部分开头相同,那么自动补全的行为还会分为两种:

    1. 如果这些可能的路径公共部分只是你输入的部分,bash不会进行补全,并给你播放\a的声音。例如:你输入的是./test,并且当前文件夹下有test.txttesttest.txt这两个文件是以test开头的。

    2. 如果这些可能的路径公共部分比你输入的部分更长,那么bash会补全到更长的公共部分,但是不会补全完整路径,并给你播放\a的声音。例如你输入的是./t,并且当前文件夹下有test.txttesttest.txt这两个文件是以t开头的。

上面的情况是对于使用bash直接进行补全,bash还提供文件路径的提示功能,如果你输入了文件路径的一部分但是发现补全不能正常进行(上述的2,3两种情况),这时可以再按一次Tab键(两次按Tab键的间隔时间不能太长,其实相当于是双击Tab键,但是太快bash可能会反应不过来),bash就可以将所有可能的路径都输出,你可以根据这个提示来完成你的命令。下面是一个例子,我的文件夹下有两个文件分别是test.txttesttest.txt。输入cat ./t并按了一次Tab键之后,bash帮我补全了test。这时我再次按Tab键就会得到下面的结果。

root@Crimmy:~# cat ./test
test.txt      testtest.txt
root@Crimmy:~# cat ./test

当前工作目录

当前工作目录(pwd, present working directory)是shell当中的一个概念。一句话来说,当前工作目录就是当前所在的文件夹。因为linux文件系统中支持相对路径,因此shell命令中使用相对路径的时候需要有一个当前位置。这个当前位置就是当前工作目录。

查看当前工作目录

一般有三种方式可以查看当前工作目录。

第一种方式是通过命令行提示符。

默认的命令行提示符中包含当前工作目录,因为我们在使用命令的时候经常需要观察当前我们所在的位置。如果你选择使用自己配置的命令行提示符,一般也建议在命令行提示符中包含当前工作目录(也可以是当前工作目录的缩写)。这是最简单的一种查看当前工作目录的方式。

自己配置命令行提示符的方式会在第20章中讲到。

第二种方式是通过pwd命令。

这个命令是GNU coreutils中的一个软件。这个命令的用法也很简单,就是输入pwd然后回车就会返回当前工作目录。

第三种方式是通过查看环境变量。如果你不知道什么是环境变量,跳过这里也没关系,环境变量的具体内容会在第20章中讲解。环境变量中有一项PWD记录当pwd路径。可以使用命令printenv PWD来查看环境变量中PWD的值。

环境变量PWD中的值可能与pwd输出的值不完全相同,这是因为linux文件系统中存在链接,导致文件系统中从根目录开始到某个节点的路径不一定唯一。更具体的内容会在第13章中讲到。

小结

这一章的内容比较简单,但是十分常用。这一章介绍了linux系统中文件路径的表示方式,包括绝对路径和相对路径。在相对路径中会使用三个特殊记号: .表示当前目录,..表示当前目录的上一级目录,~表示用户的主目录。为了在shell中表示当前位置,shell中引入了当前工作目录这个概念。有了这些基础知识之后,我们就能更方便地操作文件系统了。

当然,shell当中还有更多的和文件系统相关的命令,我们将在下一章介绍它们。