0.6 路径:绝对路径与相对路径
第〇篇【零基础预科】免费。这一篇解决一个问题:怎么用一行文字,精确告诉电脑某个文件在哪。
一、路径是什么
文件在目录树里的"位置描述"就是路径(Path) ,它把"从起点到文件经过的文件夹"一个个列出来。
Windows 用反斜杠
\分隔:C:\Users\yibo\Desktop\报告.txtLinux 用正斜杠
/分隔:/home/ubuntu/gysec/docker-compose.yml
网址
https://gysec.top/wiki/abc用的也是正斜杠/,和 Linux 一致。
你可能会问:为什么 Windows 用反斜杠
\、Linux 用正斜杠/,记不住怎么办? 这是历史遗留:早期 DOS(Windows 的前身)用反斜杠当分隔符,而 Unix(Linux 的前身)用正斜杠,几十年下来谁也没改。记忆技巧很简单——你写的这个网站地址https://...里用的是斜杠/,所以在 Linux 和网页世界里记住"斜杠"就行;Windows 的资源管理器和老命令行里才用"反斜杠"。好在现代 Windows 的 PowerShell 和大部分工具其实两种斜杠都认,你不必死记。
再补充一个关键概念:当前工作目录。你在命令行里输入一个文件名时,如果不写完整路径,系统就默认你说的是"当前所在文件夹"里的那个文件。这个"当前所在"就叫工作目录。就像你人站在某个房间里找东西,说"桌上的杯子"别人知道指哪个房间;但如果你换了个房间,同样说"桌上的杯子"指的就变了。相对路径之所以和当前位置有关,根源就在这里。
二、绝对路径:从根目录一路写全
绝对路径从最顶层的根目录出发,把经过的每一层都写出来,因此位置唯一、没有歧义。
- Windows 以盘符开头:
C:\Windows\System32\drivers\etc\hosts - Linux 以
/开头:/etc/openresty/gysec/users.json
无论你"当前站在哪个文件夹",绝对路径指向的都是同一个地方。
举个真实场景感受一下。假设你要找 Windows 的 hosts 文件,它的绝对路径永远是 C:\Windows\System32\drivers\etc\hosts——不管你是在 PowerShell 里、在 Python 脚本里、还是在某个配置文件里写这个路径,它指向的都是同一个文件。而相对路径呢?你在 C:\Users\yibo 下写 hosts,系统找的是 C:\Users\yibo\hosts(大概率不存在);你切到 C:\Windows\System32\drivers\etc 再写 hosts,这次才找对。同一个文件名,当前目录不同,结果天差地别——这就是为什么新手在命令行里最常踩的坑就是"文件明明在,却说找不到",十有八九是当前目录不对。
你可能会问:路径里的
~是什么? 在 Linux 和 macOS 里,~是"当前用户主目录"的简写。比如~/Documents就等于/home/你的用户名/Documents。这个符号在 Windows 的 PowerShell 里也开始支持了(指向C:\Users\你的用户名)。看到~不用觉得神秘,它就是主目录的代号。
三、相对路径:从"当前所在文件夹"出发
相对路径不写根,而是以你当前的工作目录为起点来描述。两个特殊符号非常重要:
| 符号 | 含义 |
|---|---|
. | 当前目录(现在站的文件夹) |
.. | 上一级目录(父文件夹) |
举例,假设当前在 /home/ubuntu/gysec/docs/:
| 相对路径 | 实际指向 |
|---|---|
index.md | /home/ubuntu/gysec/docs/index.md |
./learn/a.md | 当前目录下 learn 文件夹里的 a.md |
../deploy/publish.ps1 | 上一级 gysec 下 deploy 里的 publish.ps1 |
../../etc/hosts | 连续上两级再进 etc(可能已跳出项目) |
把 . 和 .. 用熟了,你在命令行里能少敲很多字。比如你当前在项目的 docs/learn/ 目录下,要打开上一级 docs/ 里的 index.md,不用切来切去,直接 ../index.md 就行;要回到项目根目录,../../ 一步就到。再举一个容易绕晕的例子:././a/../b/c.txt 这种路径,系统会自动把它"化简"——././ 等于什么都没干,a/../ 等于又退出来了,最终等价于 b/c.txt。你自己写的时候不用这么绕,但读别人的配置或报错时会遇到这种写法,知道它会被化简就不慌了。
还有个新手常犯的错:路径里忘了写分隔符。比如把 ./learn/a.md 写成了 .learn/a.md——在 Linux 里 .learn 会被当成一个名字叫".learn"的文件夹(而且是以点开头的隐藏文件夹),完全不是你想要的"当前目录下的 learn"。这种错误不报错、就是找不到文件,排查起来特别磨人,所以写完路径多扫一眼分隔符。
四、安全里为什么路径极其重要
- 路径穿越(目录遍历):如果程序把用户输入直接拼进文件路径,又没过滤
..,攻击者就能用../../etc/passwd跳出受限目录,读到系统敏感文件; - ZipSlip:压缩包里夹带
../路径,解压时把恶意文件写到系统目录(kkFileView 那类漏洞就涉及); - Web 根目录:Web 服务只把某个文件夹(如
/var/www/gysec)对外暴露,理解"根"才能理解哪些文件本不该被访问; - Docker 挂载、反弹 IP、配置路径:复现漏洞时几乎处处要写路径。
一个直观的防御原则:处理文件路径时,先把它规范化(解析掉所有
.和..),再确认结果仍位于允许的目录内,否则拒绝。
举一个最简单的路径穿越例子。假设一个网站允许你通过 ?file=report.txt 这样的参数读取"报告文件夹"里的文件,服务器代码天真地把参数直接拼成 ./reports/ + 用户输入。攻击者把参数改成 ../../etc/passwd,拼出来就变成了 ./reports/../../etc/passwd——化简之后就是 /etc/passwd,也就是 Linux 系统里存放所有用户名单的文件。本来你只能看 reports 里的报告,结果一个 ../ 跳到了系统目录,把敏感文件读走了。这就是为什么前面那句"先规范化、再确认还在允许目录内"不是废话——它挡住的正是这种攻击。
Docker 挂载也是同理。你在 docker run -v /本地路径:/容器内路径 这样的命令里,左边那个路径如果写错了,挂载进去的就不是你想给的那个文件夹,可能整个系统盘都被挂进容器里了,容器里的程序就能读到你宿主机的所有文件。路径这种东西,写错一个字符,安全边界可能就整个塌了。
五、本篇小结
- 路径 = 文件在目录树中的位置;Windows 用
\、Linux 和网址用/。 - 绝对路径从根出发、唯一无歧义;相对路径从当前目录出发,用
.和..。 - 安全上:路径穿越
../、ZipSlip、Web 根目录、挂载路径都建立在路径概念之上。 - 防御:规范化路径并校验其仍在允许目录内。
下一篇 0.7 回到图形界面,系统梳理鼠标、窗口、菜单、对话框的标准操作。