How to get the Path of stdout?

How to convert the std::io::stdout() to std::path::Path?

Stdout isn't a file path, what do you need this for?

1 Like

I don't think you can. It doesn't really make sense on some platforms. For example, for Windows stdout might be what's known as a "pseduo handle". Aka a special value that mean stdout.

Edit: You may be able to use the OS specific extensions to get a file object and then use the canonicalize method to get a path. This may fail though and probably isn't very robust.

2 Likes

You can use std::fs::read_link() to read /dev/fd/1 on Linux, and probably other Unix/POSIX systems. This won’t work on Windows though. As others have said, this is a platform-specific problem.

Since in Unix, everything is considered as a file. So, I was curious if stdout is considered as a file where would it be stored and what would be the path of that file

/dev/fd/1 on Linux (or modern distributions at least) is a symbolic link to the file where stdout is directed (which will be a terminal device under /dev if the program is being run interactively in a terminal). File descriptor 1 is stdout, 2 is stderr, and 0 stdin. Other open files get assigned descriptors > 2 (normally).

2 Likes

/dev/stdout is also typically a symlink to /proc/self/fd/1 which is typically a symlink to somewhere else, e.g. a pseudo-terminal. Sometimes it makes more sense to use /dev/tty.

1 Like

Not every files are stored under some path. For example, tempfile creates true temporary file by removing it from the path immediately after the creation. Single file can be accessible from zero or more paths.

5 Likes

Good point also. I have absolutely no idea which of /dev/stdout, /dev/fd/* and /proc/self/fd* is most portable though.

You're right that stdout is a file, but not all files have paths. A file is something that you can read/write to using a file interface (byte-based, with 'file descriptor'.) A path is a name for a file stored in the file system, but stdout may not be, and if it is, it may have multiple paths that refer to it.

3 Likes

Also true. Be prepared for read_link() to fail, or return an inaccessible or invalid path in some cases.

Simple example of not-a-path:

# Typical for a shell
% bash -c 'readlink /proc/self/fd/1'       
/dev/pts/11

# Could be a pipe though (or socket or ...)
% bash -c 'readlink /proc/self/fd/1' | cat 
pipe:[18678538]
4 Likes