Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Support getting canonical filesystem paths with symlinks resolved, similar to the Linux realpath utility #10640

@mklement0

Description

@mklement0

Summary of the new feature/enhancement

Provide the ability to resolve a filesystem path to its canonical path, such as by adding a -Canonical switch to the Convert-Path cmdlet.

In short: The idea is to allow you to answer the following question:

Given a (possibly relative, possibly PS-drive-based) file or directory path, where does the referenced file truly live, with symlinks, if any, resolved to their underlying target location, expressed as an absolute, native filesystem path?

For instance, say you want to know the canonical path of file
/User Guides And Information/ENERGY STAR.pdf on a Mac, which is /Library/Documentation/User Guides and Information.localized/ENERGY STAR.pdf
because /User Guides And Information is a directory symlink that targets
directory /Library/Documentation/User Guides and Information.localized

You could then do something like:

# WISHFUL THINKING
PS> Convert-Path -Canonical '/User Guides And Information/ENERGY STAR.pdf'

/Library/Documentation/User Guides and Information.localized/ENERGY STAR.pdf

On at least some Linux distros, the realpath utility provides this functionality, and you can also use readlink -f (or -m or -e).

Note that this new feature would complement the existing ability to inspect a symlink's (reparse point's) target via the .Target property of Get-Item / Get-ChildItem output, and also the proposed .ResolvedTarget property (see #13366 ).

The latter only operate on symlinks themselves, not on paths based on them (paths with additional components); additionally, the .Target property may be a relative path and $null if the input path isn't a symlink.
That is, (Get-Item '/User Guides And Information').Target works, because /User Guides And Information is itself a symlink, but (Get-Item '/User Guides And Information/ENERGY STAR.pdf').Target is $null, because the file inside the directory-symlink path itself isn't a symlink and therefore has no .Target property value.

Proposed technical implementation details (optional)

  • Windows: The GetFinalPathNameByHandle Windows API function provides this functionality.

  • macOS, Linux: haven't looked into it, but the GNU readlink utility implementation should provide pointers. The POSIX-mandated realpath() function provides this functionality (implemented as library functions on macOS and Linux; see man 3 realpath).

Decisions will also have to be made with respect to how final path components that don't exist yet are handled (i.e., a prefix of the path exists (an ancestral directory), but not the filename part or a relative subdirectory-based path), and how to handle broken symlinks; these cases are reflected in the GNU readlink utility's related -f / -e / -m options.

Note that Convert-Path in its current form doesn't support (partially) non-existent paths, but it's about time we changed that too - see #2993

Update: Implementing this functionality as a .NET API that this feature could build on, in the form of a new System.IO.Path.GetFullPath() overload, has now been proposed: dotnet/runtime#24271 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-FileSystem-Providerspecific to the FileSystem providerIssue-Enhancementthe issue is more of a feature request than a bugResolution-No ActivityIssue has had no activity for 6 months or moreWG-Cmdlets-Managementcmdlets in the Microsoft.PowerShell.Management module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions