How to follow a symbolic/soft link in cmd or PowerShell?
Asked Answered
W

3

12

My searches have only shown me how to create symbolic links using mklink in cmd. I have seen some things saying to use readlink, but PowerShell and cmd don't know what readlink is, and cd obviously doesn't work. So how do I follow one?

Wilone answered 16/2, 2019 at 22:59 Comment(0)
I
5

For your question i made this batch file:

mkdir truedir
dir > truedir\fileone.txt
mklink /d symdir truedir
cd symdir
dir

And i have found no problem to get the content of the symblic link to a directory from command prompt. No problem also with powershell 5.1 (win 10):

Get-ChildItem C:\Users\<user>\OneDrive\Desktop\test2\symdir

Can you give us a code example (batch or powershell is the same) to replicate your problem?

Isocyanide answered 16/2, 2019 at 23:28 Comment(3)
Thanks for your help. I thought .lnk files were symbolic links, but I realize that is not the case now. Do you know how to follow a .lnk? If not I can just create actual symbolic links instead.Wilone
Look here: #46276918Isocyanide
Thank you for pointing me in the right direction. Now that I have my terms straightened out, I should able to do this now.Wilone
A
19

To avoid confusion stemming from your question:

  • Windows shortcut files (*.lnk files), which are a feature of the Windows (GUI) shell, are distinct from symbolic links (symlinks), which are a feature of the (NTFS) filesystem.

  • Shortcut files - which you are interested in - store the path of a file or folder they point to inside the file, which is why:

    • You cannot directly cd to a shortcut file's target folder, because filesystem commands such as cd know nothing about the content of files.
    • You must read the content of the shortcut file to determine its target, which you can then pass to cd or Set-Location (in PowerShell).
    • The file format of shortcut file is a binary one that can be read via an in-box COM component that exposes Windows shell functionality; e.g., to determine the target folder of a shortcut file named Samples.lnk and change to that folder, use PowerShell:

      # NOTE: * Despite the name "CreateShortcut()", the method is also
      #         used to *read* shortcut files.
      #       * Prefixing the filename with "$PWD/" is needed in order
      #         to target a file in the current directory, because
      #         the method doesn't know what PowerShell's current dir. is.
      cd (New-Object -ComObject WScript.Shell).CreateShortcut("$PWD/Samples.lnk").TargetPath
      
  • Symlinks, by contrast:

    • (typically) transparently redirect to their target, i.e., the filesystem item (file or folder) they point to.

    • You can therefore use cd directly with a symlink to a folder, but note that it is still the symlink's path that is shown.

    • To print a symlink's target - akin to what the readlink utility does on Unix-like platforms - use PowerShell; e.g., to print the target of a symlink named Samples in the current directory:

       (Get-Item Samples).Target
      
       # Or, after running `cd Samples`:
       (Get-Item .).Target
      
    • Note that it's not straightforward to get a symlink's target in cmd.exe, but if you use
      dir /al <link-path>*, the listing will also show the link's target path, after the name, enclosed in [...]; note that the trailing * is necessary in order to show information about the link itself, not its target's contents; note that, although unlikely, that may match other links that start with the same path as well.


Unlike shortcut files, symlinks are still rare in the Windows world, not least because prior to Windows 10 they invariably required admin privileges to create; in Windows 10, if developer mode is enabled (by an administrator), even non-administrative users / non-elevated processes can now create symlinks - see https://blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/, which also explains why symlinks are likely to see increasing usage in the future.

Andresandresen answered 17/2, 2019 at 11:34 Comment(5)
Thanks for the extra info. Do you know how I can create hard links? Even using an elevated cmd, I can't create them. I believe this is because Windows sets all folders to be read-only by default. Unchecking the read-only box only applies to files within the folder.Wilone
@Deoxal: Hardlinks can only target files, so you need to either use symlinks (symbolic links) or junctions if you want to target folders. I suggest using symlinks, which provide the most flexibility (they can also target folders on other volumes / machines).Andresandresen
I wonder how to follow hard links. Windows apps seem to use them often, like windows terminal, $env:localappdata\Microsoft\WindowsApps\wt.exe. fsutil seems to spit out binary.Coucal
@js2010, you can't really follow hardlinks, but you can see all other paths that link to the same data. In Windows PowerShell only, you can inspect the .Target property of what Get-ChildItem / Get-Item returns (this was removed from PowerShell Core).Andresandresen
I guess the reparsepoints windows apps make are an exception. There's no target property with those. I posted a question. #71697988Coucal
I
5

For your question i made this batch file:

mkdir truedir
dir > truedir\fileone.txt
mklink /d symdir truedir
cd symdir
dir

And i have found no problem to get the content of the symblic link to a directory from command prompt. No problem also with powershell 5.1 (win 10):

Get-ChildItem C:\Users\<user>\OneDrive\Desktop\test2\symdir

Can you give us a code example (batch or powershell is the same) to replicate your problem?

Isocyanide answered 16/2, 2019 at 23:28 Comment(3)
Thanks for your help. I thought .lnk files were symbolic links, but I realize that is not the case now. Do you know how to follow a .lnk? If not I can just create actual symbolic links instead.Wilone
Look here: #46276918Isocyanide
Thank you for pointing me in the right direction. Now that I have my terms straightened out, I should able to do this now.Wilone
S
1

Okay I just posted this answer in another similar question so I figured I'd post it here too. I wish this one had come up in a search like the other question did because @mklement0's answer is great. But here is my solution that is able to follow nested links to the true file or directory in PowerShell (I was looking for a PS-specific solution, not CMD).

So far the double-cd approach is the most reliable/universal I can find for handling a situation of mixed relative/absolute paths in the filenames and targets, and I tested several scenarios.

function getLinkTarget($fn) {
    $op=$PWD #Save original path
    while($t=(Get-Item $fn).Target) { #Get link target
        cd (Split-Path -Parent $fn) #cd to parent of file/dir
        cd (Split-Path -Parent $t) #cd again to parent of target
        $fn=(Split-Path -Leaf $t) #Set filename to relative target
    }
    $fn=(Join-Path $PWD $fn) #Make path absolute
    cd $op #Change back to original path
    return $fn
}
Sandbank answered 18/2, 2023 at 0:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.