V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yezheyu
V2EX  ›  程序员

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

  •  
  •   yezheyu · 215 天前 · 962 次点击
    这是一个创建于 215 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    # 家目录~下有一个 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],
      ...
    }
    

    这是为什么呢?

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

    3 条回复    2024-04-25 18:55:54 +08:00
    yezheyu
        1
    yezheyu  
    OP
       215 天前
    如果 JavaScript 这种不依赖工作目录,只要 js 文件的所在的目录(或其上级目录)含有所需的依赖(模块),就可以正常运行。

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

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

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

    你 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
        3
    tD3H4t5jUowkHZca  
       215 天前 via Android
    重新看了下 c 代码。

    补充修正:

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

    如果是 gcc 时立刻获取 b.out 文件,则和我前一个回复一致。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6045 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:21 · PVG 10:21 · LAX 18:21 · JFK 21:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.