简体   繁体   中英

batch file (windows cmd.exe) test if a directory is a link (symlink)

I learned just now that this is a way to test in a batch file if a file is a link:

dir %filename% |  find "<SYMLINK>" && (
   do stuff
)

How can I do a similar trick for testing if a directory is a symlink. It doesn't work to just replace <SYMLINK> with <SYMLINKD> , because dir %directoryname% lists the contents of the directory, not the directory itself.

It seems like I need some way to ask dir to tell me about the directory in the way that it would if I asked in the parent directory. (Like ls -d does in unix).

Or any other way of testing if a directory is a symlink?

Thanks!

You have three methods

Solution 1: fsutil reparsepoint

Use symlink/junction with fsutil reparsepoint query and check %errorlevel% for success, like this:

set tmpfile=%TEMP%\%RANDOM%.tmp

fsutil reparsepoint query "%DIR%" >"%tmpfile%"
if %errorlevel% == 0 echo This is a symlink/junction
if %errorlevel% == 1 echo This is a directory

This works, because fsutil reparsepoint query can't do anything on a standard directory and throws an error. But the permission error causes %errorlevel%=1 too !

Solution 2: dir + find

List links of the parent directory with dir , filter the output with find and check %errorlevel% for success, like this:

set tmpfile=%TEMP%\%RANDOM%.tmp

dir /AL /B "%PARENT_DIR%" | find "%NAME%" >"%tmpfile%"
if %errorlevel% == 0 echo This is a symlink/junction
if %errorlevel% == 1 echo This is a directory

Solution 3: for (the best)

Get attributes of the directory with for and check the last from it, because this indicates links. I think this is smarter and the best solution.

for %i in ("%DIR%") do set attribs=%~ai
if "%attribs:~-1%" == "l" echo This is a symlink/junction

FYI: This solution is not dependent on %errorlevel% , so you can check "valid errors" too!

Sources

general code:

fsutil reparsepoint query "folder name" | find "Symbolic Link" >nul && echo symbolic link found || echo No symbolic link

figure out, if the current folder is a symlink:

fsutil reparsepoint query "." | find "Symbolic Link" >nul && echo symbolic link found || echo No symbolic link

figure out, if the parent folder is a symlink:

fsutil reparsepoint query ".." | find "Symbolic Link" >nul && echo symbolic link found || echo No symbolic link

Actually, DIR works fine if you append an asterisk to the filename, thus:

dir %filename%* |  find "<SYMLINKD>" && (
   do stuff
)

GreenAsJade called my attention to this solution's failure when there is another entry in the directory that matches %filename%*. I believe the following wiull work in all cases:

set MYPATH=D:\testdir1
set FILENAME=mylink
set FULL=%MYPATH%\%FILENAME%
set SP1=0
for /f "tokens=4,5 delims= " %%A IN ('dir /L /N %FULL%*') do (
    if %%B EQU %FILENAME% (
    if "%%A" EQU "<SYMLINKD>" set SP1=1
    )
)
if %sp1% EQU 0 echo It's not there.
if %sp1% EQU 1 echo BINGO!
Pause

This also works:

dir /al|find /i "java"|find /i "junction" && ( echo directory is a symlink )

Update: this solved fine my task, but as commenters noted, dir will show both directory symlinks and directory junctions. So it's wrong answer if junctions are there.


Simple dir /A:ld works fine

dir /? :

DIR [drive:][path][filename] [/A[[:]attributes]] …

/A          Displays files with specified attributes.  
attributes   D  Directories                R  Read-only files  
             H  Hidden files               A  Files ready for archiving  
             S  System files               I  Not content indexed files  
             L  Reparse Points             -  Prefix meaning not  

The appropriate DIR command is shown in the following batch file (reparse.bat) -

  ::  Specify the Directory to search
  SET directory=C:\Users\%username%\Desktop\TEST1

  ::  Results Text
  echo SEARCH OF DIRECTORY FOR REPARSE POINTS & echo.

  ::  List files with ATTRIBUTE L (Reparse Points)
  DIR "%directory%" /A:L

  echo. && echo  Notes - && echo.
  echo  There are 3 types of Reparse points: && echo.
  echo  ^<JUNCTION^> is a Directory Junction
  echo  ^<SYMLINKD^> is a Directory SymLink
  echo  ^<SYMLINK^>  is a File SymLink
  echo. && echo.

An alternative approach is to treat each of the three types of reparse point separately , in the following batch file (reparse2.bat), which can be easily modified to search only for the type of link you are interested in -

  ::  Directory to Search
  SET directory=C:\Users\%username%\Desktop\TEST1

  ::  Results Text
  echo SEARCH OF DIRECTORY: %directory% & echo.

  ::  Find FILE SymLinks in directory
  dir "%directory%" | find "<SYMLINK>" && (
    echo This is a SymLink FILE
  ) && ( echo. )

  ::  Find DIRECTORY SymLinks in directory
  dir "%directory%" | find "<SYMLINKD>" && (
    echo This is a SymLink DIRECTORY
  ) && ( echo. )

  ::  Find JUNCTIONS in directory
  dir "%directory%" | find "<JUNCTION>" && (
    echo This is a Directory JUNCTION
  ) && ( echo. ) && ( echo. )

A simple example script for Windows 10.

Info: If it exist as SymLink in %localappdata%\\MegaDownloader folder, execute MegaDownloader.exe . If it doesn't exist as a SymLink in %localappdata%\\MegaDownloader , use mklink to create SymLink PortableData path of current folder to %localappdata%\\MegaDownloader , then runs MegaDownloader.exe .

fsutil reparsepoint query "%localappdata%\MegaDownloader" | find "Substitute" >nul && GOTO MD || mklink /D /J "%localappdata%\MegaDownloader" "%cd%\PortableData" >nul 2>&1
    
:MD
"%~dp0\MegaDownloader.exe"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM