在linux文件系统中,每一个进程在运行的时候都会记录一个“当前工作目录”,英文叫current working directory。当我们在文件路径里写一个单独的“.”时,内核和shell会把它解释成这个当前工作目录本身。也就是说,“.”是一个特殊的目录名,它始终指向你此刻所在的那个文件夹。

这种机制源于unix早期的文件系统设计。文件系统把每个目录都看成一种特殊文件,而“.”和“..”是两个由系统自动创建的目录项:“.”的inode指向本目录,“..”的inode指向父目录。用户不需要手动创建它们,任何新建的目录都自带这两项。
“.”在命令行中的常见用法
最典型的场景是执行当前目录下的脚本或程序。在linux里,直接输入命令名时,shell只会去环境变量PATH里的目录去找,不会找当前目录。因此如果有一个脚本叫deploy.sh放在当前文件夹,写deploy.sh会报“command not found”,必须写./deploy.sh。
这里的“./”就是“当前目录/”的意思,合起来告诉shell:从当前目录这个位置去加载deploy.sh。下面是一段对照示例:
# 错误写法:shell去PATH找,找不到 deploy.sh # 正确写法:明确使用当前目录下的文件 ./deploy.sh # 查看当前所在目录 pwd # 切换到当前目录(相当于没动,但可刷新某些挂载状态) cd .
另一个容易混淆的点是“.”和“..”的区别。前者是当前目录,后者是上级目录。比如路径./conf/../log其实等价于./log,因为“..”回退了一层。
在脚本和配置中如何使用“.”
在shell脚本里,“.”还有一个完全不同的用法:作为内置命令source的等价符号。写成“. filename”表示在当前shell环境中读取并执行该文件,而不是开子进程。这和路径里的“.”是两回事,但符号相同。
看下面这段脚本例子,我们用“.”来加载环境变量配置:
# 定义一些变量到config.sh # config.sh内容: # export API_URL=http://127.0.0.1:8080 # export MODE=test # 使用点号命令加载,使变量在当前shell生效 . ./config.sh # 确认变量已存在 echo $API_URL
注意上面是“. ./config.sh”,第一个点是source命令,第二个点才是路径里的当前目录。很多初学者会把它们混为一谈。如果写成“./config.sh”,那就变成执行这个脚本,变量只会在子进程里生效,父shell依旧拿不到。
路径解析的底层过程
当程序调用open()这类系统函数打开“./data.txt”时,内核的vfs路径解析逻辑会先看到“.”分量,于是直接沿用task_struct里记录的pwd指针,不向上或向下遍历,只在本目录的dentry树里继续找data.txt。
我们可以用C语言简单演示获取当前目录并拼接“.”路径:
#include <unistd.h>
#include <stdio.h>
int main() {
char buf[256];
// 获取当前工作目录,相当于“.”指向的地方
if (getcwd(buf, sizeof(buf)) != NULL) {
printf("current dir is: %sn", buf);
}
return 0;
}
这段程序打印出的字符串,就是“.”在系统眼里真正代表的绝对位置。不论你怎么cd来cd去,只要没换进程,“.”就跟着变。
常见误区与注意事项
有人以为“.”是隐藏文件前缀,其实不是。以“.”开头的文件名(如.bashrc)才是隐藏文件,而单独一个“.”是目录自身。ls -a能看到“.”和“..”这两个条目,正是因为它们是真实存在的目录项。
在写docker或nginx配置时,如果用相对路径“./html”,那它是相对于配置启动时的当前目录,迁移机器后可能失效。此时清楚“.”的含义,就能判断该写绝对路径还是保持相对,避免部署出错。
| 写法 | 含义 | 是否依赖当前目录 |
|---|---|---|
| ./run.sh | 当前目录下的run.sh | 是 |
| ../run.sh | 上级目录下的run.sh | 是 |
| /opt/run.sh | 绝对路径的run.sh | 否 |
| . run.sh | source当前目录的run.sh | 是(命令意义) |
总的来说,“.”在linux路径里就是当前目录的代称,理解它既能帮你正确敲命令,也能在写程序、配环境时少踩坑。遇到路径问题,先想清楚“我现在在哪个目录”,多半就能迎刃而解。
linuxfile_pathcurrent_directory修改时间:2026-08-01 00:39:15