Как перейти по символической / мягкой ссылке в cmd или PowerShell?

Мой поиск только показал мне, как создавать символические ссылки, используя mklink в cmd. Я видел некоторые вещи, говорящие об использовании readlink, но PowerShell и cmd не знают, что такое readlink, и cd, очевидно, не работает. Итак, как мне следовать одному?

3 ответа

Решение

На ваш вопрос я сделал этот командный файл:

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

И я не нашел никаких проблем, чтобы получить содержимое символьной ссылки на каталог из командной строки. Нет проблем также с powershell 5.1 (win 10):

Get-ChildItem C:\Users\ssacc\OneDrive\Desktop\test2\symdir

Можете ли вы дать нам пример кода (пакет или PowerShell - то же самое), чтобы повторить вашу проблему?

Чтобы избежать путаницы, связанной с вашим вопросом:

  • Файлы ярлыков Windows ( *.lnk файлы), которые являются функцией оболочки Windows (GUI), отличаются от символических ссылок (символических ссылок), которые являются функцией файловой системы (NTFS).

  • Файлы ярлыков - которые вас интересуют - хранят путь к файлу или папке, на которые они указывают, внутри файла, поэтому:

    • Вы не можете напрямую cd в папку назначения ярлыка файла, потому что команды файловой системы, такие как cd ничего не знаю о содержимом файлов.
    • Вы должны прочитать содержимое файла ярлыка, чтобы определить его цель, которую затем можно передать cd или же Set-Location (в PowerShell).
    • Формат файла ярлыка - это двоичный файл, который можно прочитать через встроенный COM-компонент, который предоставляет функциональность оболочки Windows; например, чтобы определить целевую папку файла ярлыка с именем Samples.lnk и перейдите в эту папку, используйте 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
      
  • Симлинки, напротив:

    • (обычно) прозрачно перенаправить к своей цели, то есть к элементу файловой системы (файлу или папке), на который они указывают.

    • Поэтому вы можете использовать cd непосредственно с символической ссылкой на папку, но обратите внимание, что это все еще путь симлинка, который показан.

    • Чтобы напечатать цель символической ссылки - сродни тому, что readlink утилита работает на Unix-подобных платформах - используйте PowerShell; например, чтобы напечатать цель символической ссылки с именем Samples в текущем каталоге:

       (Get-Item Samples).Target
      
       # Or, after running `cd Samples`:
       (Get-Item .).Target
      
    • Обратите внимание, что не просто получить цель символической ссылки в cmd.exe, но если вы используете
      dir /al <link-path>*в списке также будет показан целевой путь ссылки после имени, заключенного в [...]; обратите внимание, что трейлинг * необходим для отображения информации о самой ссылке, а не о ее цели; обратите внимание, что, хотя и маловероятно, это может соответствовать другим ссылкам, которые также начинаются с того же пути.


В отличие от файлов ярлыков, символические ссылки все еще редки в мире Windows, не в последнюю очередь потому, что до Windows 10 они неизменно требовали прав администратора; в Windows 10, если включен режим разработчика (администратором), даже пользователи без прав администратора / процессы без повышенных прав теперь могут создавать символические ссылки - см. https://blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/, которая также объясняет, почему символические ссылки, вероятно, будут расширяться в будущем.

Хорошо, я только что опубликовал этот ответ в другом подобном вопросе, поэтому решил опубликовать его и здесь. Я бы хотел, чтобы этот вопрос появился в поиске, как и другой вопрос, потому что ответ @mklement0 великолепен. Но вот мое решение, которое может переходить по вложенным ссылкам на истинный файл или каталог в PowerShell (я искал решение для PS, а не CMD).

На данный момент подход с двойным cd является самым надежным/универсальным, который я могу найти для обработки ситуации смешанных относительных/абсолютных путей в именах файлов и целевых объектах, и я протестировал несколько сценариев.

      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
}
Другие вопросы по тегам