I've finally come across a relatively robust way to test if a path points to a directory or a file when writing Windows batch files.

 

I was troubleshooting a backup script that I had found several years ago and customized. The problem was that to test if a path was a directory or a file the script just checked whether the path had an extension. Works great for most files. However, I had several files that didn't have a file extension. So the script treated it as a directory, which wouldn't have been a problem except that when you supply the same filename in both the source and the destination, xcopy asks if you're trying to copy a file or a directory. Since this is an automated script that spits all of its output into a log file, it would hang with no indication to the user what was going on. Moreover, automated scripts should not randomly ask for user input in the middle of execution, that's why they're automated.

 

From my very limited perl and unix scripting experience I knew that they each had a simple way to test if a path was a file or a directory. However I hadn't come across anything similar in Windows batch files. Finally, I came across a discussion on stackoverflow.com which provided the needed solution. Most of the suggestions in response to the question "How do I test if a file is a directory in a Batch script?" were along the lines of what I already had in the script or had reliability issues as discussed in the thread, but near the end was a suggestion to parse the file attributes and if it started with a "d" then it is a directory.

 

The final solution was to save the attributes of the path into a variable and then test the first character of that variable to determine whether it is a directory or a path. The benefit to this approach is that it should also work when the directory name contains a period, since previously it would have been treated as a single file. An example batch file is shown below.

 

@echo off
SETLOCAL ENABLEEXTENSIONS
set ATTR=%~a1
if /I "%ATTR:~0,1%"=="d" echo %1 is a folder
:EOF

 

Also remember that if the variables are set inside of a FOR loop to replace the "%" with "!".