请教一个关于工作目录的疑问

210 天前
 yezheyu

工作目录按我的理解是一个软件运行时所在的目录,软件内部使用的路径中...会使用工作目录作为参考

# 家目录~下有一个 b.out 的程序
~$ cat b.c
#include <stdio.h>
int main() {
    printf("Hello, World!\n");
    return 0;
}
~$ gcc b.c

# ~/Project 下有一个 a.out 程序,其会调用 b.out(使用的是相对路劲)
~$ cd Project
~/Project$ cat a.c
#include <stdio.h>
#include <unistd.h>
int main() {
    char *args[] = {"./b.out", NULL};
    if (execvp(args[0], args) == -1) {
        perror("execvp failed");
        return 1;
    }
    return 0;
}
~/Project$ gcc a.c

# 在 b.out 所在的家目录下调用 a.out ,工作目录是~,使用./b.out 能找到 b
~/Project$ cd ~
~$ ~/Project/a.out
Hello, World!

换成 node 、python 这种解释型语言,发现就和我想的不一样了

# ~/Project 目录下存在 vue 模块
~/Project$ ls node_modules
vue    @vue   vie    @vitejs

# 在家目录~下存在一个 a.js ,其使用 vue 模块
~/Project$ cd ~
~$ cat a.js
let vue = require('vue');
console.log(vue);

# 在~/Project 目录下运行 a.js
# 当前工作目录下存在 vue 模块,但 a.js 文件所在的目录以及其上级目录不存在 vue 模块
~$ cd Project
~/Project$ node ~/a.js
...
Error: Cannot find module 'vue'
Require stack:
- /home/yezheyu/pwd.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1143:15)
    at Module._load (node:internal/modules/cjs/loader:984:27)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
...


# 让 a.js 文件所在的路径包含 vue 模块
~/Project$ mv ~/a.js ~/Project

# 在~目录下运行 a.js
# 当前工作目录下不存在 vue 模块,但 a.js 所在的目录下包含 vue 模块,运行不会报错
~/Project$ cd ~
~$ node ~/Project/a.js
{
  EffectScope: [class EffectScope],
  ReactiveEffect: [class ReactiveEffect],
  customRef: [Function: customRef],
  effect: [Function: effect],
  ...
}

这是为什么呢?

是解释器有着一套自己的相对路径解析策略

956 次点击
所在节点    程序员
3 条回复
yezheyu
210 天前
如果 JavaScript 这种不依赖工作目录,只要 js 文件的所在的目录(或其上级目录)含有所需的依赖(模块),就可以正常运行。

所以运行前段项目时,完全可以不进入项目所在的目录启动项目

直接在家目录也可运行项目?

`~/Project/node_modules/vite/bin/vite.js`
tD3H4t5jUowkHZca
210 天前
感觉你理解错了。

你 gcc a.c 的时候,是根据 a.c 里面的代码来寻找 b.out ,和 gcc 执行时所在位置无关,和 a.c 的位置及其代码有关。

node ,python 同理。

node ~/a.js ,a.js 在 ~, 而它引用的 vue 却在~/Project/node_modules 里,a 自然无法引用到 vue ,和 node 的执行路径无关。

npm 项目有 package.json 和 node_modules ,你需要把 js 文件放在同级目录或子目录才能通过 require();引用到对应包。
tD3H4t5jUowkHZca
210 天前
重新看了下 c 代码。

补充修正:

gcc a.c 的时候并没有立刻去获取 b.out ,而是在执行 a.out 的时候才临时获取,因此这时和你执行 a.out 所在的路径有关。

如果是 gcc 时立刻获取 b.out 文件,则和我前一个回复一致。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1035509

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX