Test whether a certain file or folder exists

In we will:

 Note 1  Each Lesson relies on your files from the previous one. It's better to use your own files, but if you can't, download a copy of files as they were at the end of Lesson 9 and click instructions. Remember you can if you prefer.

 Note 2  For a very detailed account (with many examples) of how to insert fixed-time delays in batch files (in other ways than using ), how to wait for a Windows process to finish, or wait for an event (in another batch file), see our Batch Reference.

Check folder exists before we Add Files to it

The Add Files section of the script will add a few new files, and make a few changes to existing ones. Before we do this, we should be sure the folder exists.

We know it exists at the moment. And, even if we deleted it, we wouldn't use the  A  option to add files before we used the  B  option to build the folder – would we? Possibly not, but let's look at how we can make our script check and warn us properly.

Testing that a file exists

We've seen that the command can be used to test for an return code. can also test whether or not a file exists.

Let's remind ourselves what files exist in C:\CSW by using to list them :

The test

We can test whether or not a particular file exists, and carry out some command on the success (or failure) of the test. The syntax to test whether or not a file, for example HW.BAT, exists is:

if exist hw.bat echo.Yes, it exists

The Command that is (conditionally) executed can be whatever you please; but the simple command above will demonstrate how the test works :

A true test executes the conditional command

The condition is true, HW.BAT does exist. And so the associated command is executed, and we see the message on the screen.

A false test doesn't

When the test is false, the associated command isn't executed. Try an existence test for a file we know doesn't exist, mxyzptlk.txt :

The file doesn't exist, so the command isn't executed.

Testing that a file doesn't exist

As with the test, we can use NOT to reverse the logic of the test. In this case the associated command is executed only if the file doesn't exist :

Testing for folders:
The test fails when testing for a folder

 
The test is for files, not folders. We know the folder C:\CSW exists, but the test won't work for it. Check this :

The test reports wrongly for foldernames

And, consequently, if you try a simple NOT test on the C:\CSW folder, your test will (wrongly) report that it doesn't exist :

The test is purely file-oriented. It fails for the folder C:\CSW. This is despite the fact that (technically) there is a file called C:\CSW that holds the contents list for the folder. The test ignores such files, because they have the special directory attribute set.

A with

You can use a in an test. For example, we know there are .BAT files in C:\CSW. We can test for any such file with the *.BAT (=any file with extension BAT). Try it now :

A conditional

As we said, the command that is (conditionally) executed doesn't have to be . For example, we could test whether or not any .BAT files exist, and then list all our files in the Course folder only if some .BAT files are present :

When a fails the command isn't run

We know that we don't have any .DLL (Windows Dynamic Link Library) files in C:\CSW, so a test for them (correctly) fails to run the command :

A to test whether a folder exists?

The *.* represents any file with any extension. We can use it to test whether or not any file at all exists in a folder, so perhaps it could form the basis of a test whether or not a folder exists (in fact, this won't work, as we'll see).

We know that C:\BKTEST exists at the moment, and that it does have some files in it, so let's try the test :

So far, so good. The test works in this case and so could be a candidate for testing whether or not a folder exists.

The *.* test is false for a non-existent folder

We know the folder C:\CSW\NEW doesn't exist, so if we test for any files in it, the test will fail. Let's check :

No message is echoed, because no such files exist. Therefore, so far, the test does appear to test correctly for a folder's existence (if it contains any files), and it tests correctly for a folder's non-existence.

Create an empty folder

Now create the folder C:\CSW\NEW with :

The test fails if there are no files in a folder

Repeat the test for any file in C:\CSW\NEW :

The test fails because, although the folder exists, there are no files in it.

Create a single file

Now, create a single file in the NEW folder with . Use a relative path this time, in other words, leave out the C:\CSW\ part of the file specification :

Since C:\CSW is the current folder, we can equally well use the simpler, relative path new\5THDIM.TXT to the file 5THDIM.TXT.

It's equally valid to use the full path c:\csw\new\5THDIM.TXT for our note about Mr Mxyzptlk (pronounced "mix-yus-pitalik" actually).

Now the test is true

Now repeat the test for any file in the new folder :

At least one file is needed. This means the test for *.* isn't a proper check that a folder exists. It's fine if any files are present, but it won't test for empty folders.

Testing for the

The system (which we have used with to suppress messages) is treated as a file by Windows. Try a simple existence test :

The file "exists" in every folder

Windows regards as a file that "exists" in every local disk folder. Check the C:\CSW\NEW folder again, but this time use the method :

Remove the only file

The test confirms that is technically there in the NEW subfolder. Now remove 5THDIM.TXT which is the only real file :

Check for again

Check the C:\CSW\NEW folder again :

The test works even for empty folders

Unlike the *.* , the test remains true even when the folder is empty. Let's confirm it becomes false when the folder itself is removed. The NEW folder is empty, so we can remove it with a simple command :

Confirm the test is now false

Test for the existence of the C:\CSW\NEW folder one more time with the test. This time there is no Yes message, and so the test confirms correctly that the folder doesn't exist :

Confirm negative test evaluates as true

And finally, check that the NOT version of the test is true for a non-existent folder, since this is the check we'll make in our script :

 Note  The test is useful, but it doesn't work across a network to test for the existence of network drives (nor with some very old drive types using legacy drivers).

Testing in the script:
Add existence test to BKSETUP.BAT

 
In the script, we'll expand the variable SRC in which we store our test folder name.

In immediate mode we would use:   IF NOT EXIST C:\BKTEST\NUL
In our script we'll use: IF NOT EXIST %SRC%\NUL

If the folder doesn't exist, we need to jump to the :E_FOLDER section, where we display the error message for this problem. Remember, it's conventional to leave out the  :  from the label when you use the command. The line we need is therefore:

IF NOT EXIST %SRC%\NUL GOTO E_FOLDER folder not found

The line will go in the :ADDFILES section. Since we can't do anything in this section if the folder doesn't exist, it's best to put this check as the first line of the section

Open BKSETUP.BAT script in Notepad

Open the BKSETUP.BAT script in Notepad with a command :

Add test to the script

The test line goes in the :ADDFILES section. We'll test that the folder exists before the TASK message is set, since we can't do anything about adding files if we haven't built the folder first :

The :E_FOLDER section can be finished now

When this error occurs, it probably means we pressed  A  at the main menu, when instead we meant to press  B . So the sensible thing to do once we've jumped to the :E_FOLDER section is to display the error message, and then jump back to the main menu.

We have the :MAINMENU label in place already, so we can simply write a suitable command in the :E_FOLDER section. Add the jump now :

First delete the folder

You clicked File, Save so we can test the error check. First, we shall need to delete the C:\BKTEST folder, so that the "folder not found" error occurs. Use to remove the folder completely :

Test the script

Now run the script to test it. Choose  A  and note what happens :

Quit the menu for now

Before we discuss what's gone wrong, let's break out of that. Press  Q  to quit from the script :

What has gone wrong?

We've discussed three debug methods for script errors:

  1. debug mode shell (using command /y /c bksetup.bat to run line-by-line)
  2. Selective , with ECHO ON and @ECHO OFF around problem code
  3. and to create breakpoints in the script
We'll use and to create a breakpoint that will show what is going wrong.

We should have seen the error message

Since we expect to see the new error message, let's put a breakpoint just after it to see if we ever get there. We'll a message and add a command.

displays the message Press any key to continue . . . and waits for you to press a key. messages are particularly useful when you need to put in several commands. They make sure you know exactly which one you've paused at.

Add the breakpoint

Add the two lines in the :E_FOLDER section, just before the line :

Test the script again

You clicked File, Save, so run the script again. Choose  A , as before :

The error message is gone before we see it

Now we see that the error message about the missing folder is displayed, and we've paused, waiting to jump back to the main menu. Look at the :MAINMENU section of your script now :

The main menu clears our message

As soon as we jump back to :MAINMENU the next instruction is , which clears the screen (before our main menu is re-displayed). When it clears the screen, it clears away our error message. Let's break out of the loop :

Remove the breakpoint

Let's remove our breakpoint lines; they've done their job :

Correcting our mistake

Your PC is so fast that you don't see the error message before it's cleared away again. We could leave a command in the script, so that we have time to see the error message, but then you'd need to press  Return  to continue. Ideally, our script should display the message for a few seconds, then jump back to the main menu.

Timed delays in a script

A simple way of introducing short delays into a running script is to use a feature of the command that we haven't used so far. The /t switch allows you to specify one reply as a default, to take effect after a delay from 1 to 99 seconds. The syntax is:

choice /c: ReplyList  /t DefaultReply , TimeOut 

The exact reply list doesn't matter. Nor does it matter which key in the list we set as the default. All we want out of this command is a delay! So we can make the reply list just one letter, d (for delay); and also make that d the timeout default. We'll set the timeout to 3 seconds :

All we care about is the delay, nothing more

It's important to realise that we're not trying to get a reply from the script user with this command. We don't care about the returned (it will be 1). We're only here for the delay, and nothing more. The Batch language is feature-poor, so you often need to make up for its deficiencies with ingenuity.

We don't need to see the reply list (nor the default reply –  D  in this case – Windows supplies). We can suppress both with to . And since the reply list is irrelevant we can add the four letters "elay" and make the reply list /c:delay. Then the command is self-documenting. Try this version :

 Note 1  Using a side-effect of a command to achieve something new (for which the command wasn't directly intended) is a very common technique in scripting.

 Note 2  There is a technical problem with this simple delay command. If you press any key not in the /c: list during the delay, the timeout switch is cancelled and the command hangs waiting for a correct key. We'll see how to fix this in a later Lesson when we cover the use of s. For now, this form of the delay command will be good enough, as long as we remember the problem.

Add the delay to our script

The three-second delay is about right for our script. Remember you can use any number from 1 - 99 (instead of 3) to achieve a different delay.

Add the delay to our script. It needs to go in the :E_FOLDER section just after we display the error message, so the message stays there for three seconds before we jump to the main menu and it's cleared.

Test the script again

You clicked File, Save? Now run the script, and reply  A  at the menu. For 3 seconds we see the error message, then we're returned to the main menu. Once there, choose the  B  option to rebuild the test folder :

The delay allows us to read the error message

After three seconds to read the error message, we return to the main menu. This is exactly what we wanted. Short delays (using this feature of the command) are useful in scripts.

Test the  A  option again

Run the script again, and select the  A  option :

Only the "Add files" code remains to write

All that remains with BKSETUP.BAT is to add the code for the  A  option and test the script properly. But we'll finish now, and leave that for the next Lesson.

What we have learnt

In this Lesson we have learnt how to:

 Note  For a very detailed account (with many examples) of how to insert fixed-time delays in batch files (in other ways than using ), how to wait for a Windows process to finish, or wait for an event (in another batch file), see our Batch Reference.

The Index has the Syllabus for the next Lesson, where we'll finish our BKSETUP.BAT script. See you then.

© Copyright 2003- Allen & Company. All rights reserved ©