94

I would like to translate this Linux/Bash script to Windows shell:

if test -d myDirName; then echo "ok"; else mkdir myDirName; fi

It tests if a directory exists, and if it doesn't it creates it.

studiohack
  • 13,468
  • 19
  • 88
  • 118
Pietro
  • 1,709
  • 5
  • 24
  • 36
  • 6
    The actual linux/bash command would simply be: `mkdir -p myDirName`. After spending days trying to translate relatively simple bash-scripts into batch-sh*t (assigning the result of a function to a variable?), I've decided to just make people install cygwin. – michael Mar 30 '13 at 11:00

10 Answers10

114
@echo off
IF exist myDirName ( echo myDirName exists ) ELSE ( mkdir myDirName && echo myDirName created)

Added by Barlop

While the above works for this particular situation, the title says about testing specifically for a directory. Phogg's comment using if exist mydirname\ rather than if exist mydirname is the way. Some answers have used \nul but \nul is problematic in NT. Not including a trailing backslash will test for a file or a directory. So, for a directory, include the trailing backslash.

barlop
  • 23,380
  • 43
  • 145
  • 225
Sathyajith Bhat
  • 61,504
  • 38
  • 179
  • 264
  • 29
    This is correct for testing file existence, but how do you know that it's a directory? The simplest answer is `if exist mydirname\ ` and the rest as you say. Alternately, you could actually get a `test` binary and use it on Windows. – phogg Dec 06 '10 at 16:58
  • @phogg: In the context of this specific question: if it exists but is a file, you *still* cannot `mkdir` it. – u1686_grawity Dec 06 '11 at 13:09
  • @grawity: If it exists but is a file the script will probably fail later when trying to use it as a directory, which probably isn't what you want. – phogg Dec 06 '11 at 13:30
  • how can i check if not exist? – Sungguk Lim Jan 09 '14 at 06:43
  • 1
    @sunglim by writing ` If not exist myDirName\ ` similarly `if not 1==1 echo hmm` or if exist myDirName\ ELSE blahblahblah – barlop Jun 03 '14 at 11:13
  • Verifying it's a directory is apparently "a bit" more compicated. See https://stackoverflow.com/questions/21033801/checking-if-a-folder-exists-using-a-bat-file and https://stackoverflow.com/questions/8666225/how-to-test-if-a-path-is-a-file-or-directory-in-windows-batch-file/ for details and solutions. – Egor Hans Mar 05 '21 at 09:14
23

Here is what I just found out:

You can test if a nul file exists; if the directory exists it will contain a nul file, if the nul file does not exist then the directory does not exist.

IF exist myDirName/nul ( echo myDirName exists ) ELSE ( mkdir myDirName && echo myDirName created)
Sathyajith Bhat
  • 61,504
  • 38
  • 179
  • 264
dev008
  • 231
  • 2
  • 2
  • 2
    +1 - this works in all Windows and MS-DOS versions, unlike plain `if exist dirname` which appears to be specific to Windows NT. – u1686_grawity Dec 06 '11 at 13:09
  • that's wAS a stupid code compare to linux mkdir -p myDirName :p – TheOneTeam Jan 04 '13 at 09:35
  • 7
    It should be a backslash, not a forward slash. – Nathan Garabedian Feb 01 '13 at 23:08
  • @grawity What do you think of this though, apparently some issue with doing \nul? http://www.dostips.com/forum/viewtopic.php?f=3&t=4913 – barlop Jun 03 '14 at 11:03
  • @barlop: I think that cmd.exe is one of the worst scripting languages in existence, and that one should use PowerShell or other alternatives if at all possible. As for `\nul`, it is not necessary in Windows NT anymore, plain `if exist "C:\Program Files (x86)"` should work (unless you're still targetting Windows 98...) – u1686_grawity Jun 03 '14 at 11:17
  • @KitHo: You are comparing different pieces of code. Linux `mkdir -p myDirName` is equivalent to Windows `mkdir myDirName`, without any extra options. However, they _don't do the same thing_ as dev008's example does. – u1686_grawity Jun 03 '14 at 11:18
14

Use a backslash, not forward slash: myDirName\nul not myDirName/nul

md foo 
echo.>bar 
for %I in (foo bar xyz) do @( 
  if exist %I ( 
    if exist %I\nul ( 
      echo -- %I is a directory 
    ) else ( 
      echo -- %I is a file 
    ) 
  ) else ( 
    echo -- %I does not exist 
  ) 
)

-- foo is a directory
-- bar is a file
-- xyz does not exist

edit: this only works if directory name does not contain spaces

DVF
  • 141
  • 1
  • 3
7

Some have suggested doing \nul, but that doesn't seem to work reliably in NT

C:\blah>md abc

C:\blah>if exist abc\nul echo yes
yes

C:\blah>if exist "abc\nul" echo yes

C:\blah>

http://www.dostips.com/forum/viewtopic.php?f=3&t=4913

foxidrive writes-

The trick with nul worked in pre NT versions of windows.

Now you would use this, with a trailing backslash.

if exist "C:\abcde\" echo the folder exists

Re the question

C:\blah>if exist "abcd\" (echo yes) else (echo no && mkdir abcd)
no

C:\blah>if exist "abcd\" (echo yes) else (echo no && mkdir abcd)
yes

C:\blah>
barlop
  • 23,380
  • 43
  • 145
  • 225
4

I wondered why joe had a downvote as I was experiencing the same kind of problem on Windows 7, namely that

IF EXIST filename\NUL

was returning TRUE for both files and directories. I found an alternative solution at www.robvanderwoude.com/battech_ifexistfolder.php and came up with a revised version of DVF's FOR loop:

FOR %I in (foo bar xyz) DO @( PUSHD %I && (POPD & echo -- %I is a directory) || ( IF exist %I ( echo -- %I is a file ) ELSE ( echo -- %I does not exist ) ) )
Damian
  • 41
  • 1
  • That was the only solution that worked, thanks.   I added a "2>NUL" to avoid the error message and changed the echo values to 1 (directory exists), 0 (directory does not exist), -1 (a file with the same name exists)   FOR %A IN ("C:\temp\foo\HELLO WORLD5") DO @(PUSHD "%A" 2>NUL && (POPD & ECHO 1) || (IF EXIST %A (ECHO -1) ELSE (ECHO 0 – Christoph Sep 17 '18 at 13:01
  • (sorry, I didn't manage to format the code as code in the reply although I tried so many things :-( until editing the comment timeouted after 5 mins :-( ) – Christoph Sep 17 '18 at 13:10
2

I see many have problems with differentiating between files and folders. Has anyone tried to simply cd into it after checking it exists? Then cd will either succeed or fail.

set MyDir = "MyTestDir"
IF exist MyDir (
    cd MyDir 
    IF ERRORLEVEL NEQ 0 (
        echo "Error: %MyDir% already exists, but it is a file!"
        exit 1
    ) else (
        # Do not forget to cd back
        cd ..
    )
) else (
   # Did not exist yet, so create it.
   mkdir MyDir
)
  • (1) If you’re going to use a variable, use the variable. All occurrences of `MyDir` after the first line should be `%MyDir%`. (2) The `cd ..` won’t do what you want if `%MyDir%` is a multi-level pathname (e.g., `Pictures\cats`) or even an absolute pathname (e.g., `\Windows`). Consider using `pushd`/`popd` and/or `setlocal`. – Scott - Слава Україні Jun 03 '14 at 17:02
1

Here's a way to test the directory exists only when its a valid directory.

set myDirName=foobitybarbitybaz
dir /A:D %myDirName% >nul 2>&1
if ERRORLEVEL 1 (@mkdir %myDirName%) else (@echo "ok")

Mason M.
  • 11
  • 2
0

I prefer using dir /d | findstr \[\.\.\]:

2>nul dir /d "myDirName" | findstr \[\.\.\] >nul && echo= "ok" || mkDir myDirName&&echo= Is NOT dir


2>nul dir /d "myDirName" | findstr \[\.\.\] >nul && echo= "ok" || mkDir myDirName


For create if exist or not and for ignore error...

2>nul mkDir myDirName

Also ...

if exist "myDirName\." (echo/"ok") else mkdir myDirName

rem :: or direct create myDirName hidden/ignoring error
       2>nul mkdir myDirName & if exist "myDirName\." echo/ exist 
rem :: output: exist 
Io-oI
  • 7,588
  • 3
  • 12
  • 41
0
exist myDirName/nul

also is true if myDirName is a file, whis is not the searched functionality

Joe
  • 11
  • 1
    `C:\blah>touch abeC:\blah>if exist abe\nul echo err C:\blah>if exist abe/nul echo errC:\blah>` i'm no fan of \nul in NT but it isn't. You should have given some output. – barlop Jun 03 '14 at 11:17
-1

Finding a folder shouldn't be this difficult. My solution, use perl:

for($cnt=$#ARGV; $cnt>=0; --$cnt)
{
   if ( -d "$ARGV[$cnt]" ) { 
      print "argv[$cnt]=$ARGV[$cnt] is a folder\n";
      $dir = $ARGV[$cnt];
      break;
   } else {
      print "argv[$cnt]=$ARGV[$cnt] is Not a folder\n";
   }
}