Different output of env::current_dir()


#1

There is something I do not understand here, and could not get what is my mistake!

The code let path = env::current_dir()?; output is not the same every where!!
When I run cargo run the path I’ve is correct: /Users/hasan/Documents/PycharmProjects/hello-rocket, but when I run the executed file from the released folder, the path I’ve is only: /Users/hasan !!

use std::env;

fn index() -> io::Result<NamedFile> {
    let path = env::current_dir()?;
    
    // If run using `cargo run` use:
    // let static_files = format!("{}/static/index.html", path.display());
    //   
    // If run from executed file use:
    let static_files = format!("{}/Documents/PycharmProjects/hello-rocket/target/release/static/index.html", path.display());
    println!("The current directory is {} and index file path is: {}",
             path.display(),
             static_files
    );
    
     NamedFile::open(staatic_files) //    // NamedFile::open("static/index.html")
}

#2

Hi @hasanOryx, the env::current_dir() is a function that returns the current working directory (a directory where you executed the binary). So the output will be different, depends on your path location when you execute the binary.

related docs: https://doc.rust-lang.org/std/env/fn.current_dir.html


#3

Thanks @pyk, I executed the file from the released folder, so the path should be: /Users/hasan/Documents/PycharmProjects/hello-rocket/target/released but it give me /Users/hasan only!!

Anything wrong in m understanding!


#4

It’s not the path of the binary itself but rather the directory where you executed it from (unless code changes it programmatically).


#5

@vitalyd I opened the release folder in the finder, then double clicked the execution file, is this means when I do so, I’m in the /Users/hasan not in the /Users/hasan/Documents/PycharmProjects/hello-rocket/target/released?


#6

I’m not a Mac user so don’t know how Finder interacts with cwd, but try running it from a terminal, both while being in the /Users/hasan directory and then also in the /Users/hasan/Documents/PycharmProjects/hello-rocket/target/released one.


#7

Yes, that directory can be anything.

cd /foo/bar/baz
/Users/hasan/Documents/PycharmProjects/hello-rocket/target/released

And your current dir will be /foo/bar/baz, which has absolutely nothing to do with your program.

If you need data files in your program, then:

  • include_bytes!() will hardcode data inside your executable. That’s very useful if you need some internal data that the user doesn’t need to touch.

  • Combine env::args().nth(0) with Path::join() and fs::canonicalize() to get absolute path relative to the executable. That’s reasonable for data files distributed with the program, e.g. for a game.

  • Allow user to specify the path on command line

  • Use standard system directories for the data files


#8

Thanks @kornel, I tried include_bytes!() as below:

let index_file = include_bytes!("static/index.html");
NamedFile::open(index_file)

But got the below error:

the trait std::convert::AsRef<std::path::Path> is not implemented for [u8; 252]


#9

I managed to get the relative path as below:

    let executable = env::current_exe()?;
    let path = match executable.parent() {
        Some(name) => name,
        _ => panic!()
    };
    let index_file = format!("{}/static/index.html", path.display());

#10

I think you want something like concat!(env!(CARGO_MANIFEST_DIR), "/static/index.html). You can reference directories relative to your Cargo.toml’s parent directory that way.


#11

That’s because it doesn’t give you file path, only bytes contained in the file. Any information where the file was is forgotten.