Redirecting command-line output to keep error mess

2019-02-20 16:07发布

I'm testing the existence of a folder, and, depending on its existence, I want to run different commands:

DIR %MYDIR%\tmp > test.txt
IF ERRORLEVEL 1 (
      echo/FOLDER DOES NOT EXIST
) else (
      echo/FOLDER EXISTS
      )

The problem is that if the folder doesn't exist I'm getting this error in addition to the standard output:

The system cannot find the file specified.

I'd like to display the correct output without getting the error.

3条回答
不美不萌又怎样
2楼-- · 2019-02-20 16:20

Use exist instead:

@echo off
if exist %MYDIR%\tmp (
  dir %MYDIR%\tmp > test.txt
  goto EndIt
)
echo %MYDIR%\tmp not found > test.txt
:EndIt
查看更多
趁早两清
3楼-- · 2019-02-20 16:26

How about this:

DIR %MYDIR%\tmp > nul 2>&1

"> nul" means to redirect standard output to the file nul (the bit bucket).

"2>" is used to redirect standard error (descriptor 2). So "2>&1" is used to redirect standard error to means that standard output (descriptor 1 -- so "> null and 1> null are be the same). Alternatively you could use "2> nul".

查看更多
我想做一个坏孩纸
4楼-- · 2019-02-20 16:27

You might have run into a common problem that I have seen many times in my own scripts: not expecting a space in the file path.

The value of the MYDIR environment variable might have a space in it. When there is are spaces in a path, most commands see it as multiple parameters since spaces are used to separate parameters. So, in your case if MYDIR is C:\Documents and Settings\Jim\My Documents then your script would be attempting to perform a directory listing on several parameters:

  • C:\Documents
  • and
  • Settings\Jim\My
  • Documents

Try this in a command prompt:

C:\> mkdir learn

C:\> cd learn

C:\learn> mkdir peas and carrots

C:\learn> dir

 Volume in drive C is OS
 Volume Serial Number is 7199-C950

 Directory of C:\learn

10/03/2012  07:26 PM    <DIR>          .
10/03/2012  07:26 PM    <DIR>          ..
10/03/2012  07:26 PM    <DIR>          and
10/03/2012  07:26 PM    <DIR>          carrots
10/03/2012  07:26 PM    <DIR>          peas

Hmmm, three folders named "peas", "and", "carrots", (sorted alphabetically as is my preference for the dir command). To create a folder with spaces in the name, you must put quotes around the folder name:

C:\learn> mkdir "peas and carrots"

C:\learn> dir

 Volume in drive C is OS
 Volume Serial Number is 7199-C950

 Directory of C:\learn

10/03/2012  08:10 PM    <DIR>          .
10/03/2012  08:10 PM    <DIR>          ..
10/03/2012  07:26 PM    <DIR>          and
10/03/2012  07:26 PM    <DIR>          carrots
10/03/2012  07:26 PM    <DIR>          peas
10/03/2012  07:29 PM    <DIR>          peas and carrots
               0 File(s)              0 bytes
               6 Dir(s)  49,670,320,128 bytes free

To correct this problem in your case, add quotes around the file/folder path:

DIR "%MYDIR%\tmp" > test.txt

That eliminates the system cannot find the file specified even if the file does exist problem.

Unfortunately, if the file/folder really does not exist, you will get that same error message. If you are insistent upon using the DIR command for this, then you will have to redirect stderr stream. You have already redirected stdout using the > redirect operator. To redirect stderr to the same file, your command should look like this:

DIR "%MYDIR%\tmp" > test.txt 2>&1

Based on the output messages of your batch file, I am assuming you are only interested in determining if %MYDIR%\tmp exists, and you do not actually want the directory listing of %MYDIR%\tmp left in a file called test.txt in the current working directory. If you are simply checking if a file/folder exists, then using the DIR command is a pretty bad choice. If %MYDIR%\tmp is a folder, then the script would be wasting time retrieving the directory information for every file in that folder. If there are thousands of files in that folder, it could result in a noticeable delay. In addition, you have deposited a file named test.txt in the current working directory which you should delete before you script exits... you know... assuming you didn't really want that file in the first place.

If you simply want to know if the folder or file exists there is a much better choice: The if exist command is perfectly suited for your needs. To find out more about the if command, in a Windows Command Prompt window, type: if /?

Example:

C:\> if /?
Performs conditional processing in batch programs.

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

At first glance the documentation implies that if exist works with files only, but rest assured it does work with folders as well as files.

As you are reading through the if command's documentation, you may come across the phrase "if Command Extensions are enabled ..." On most systems Command Extensions are enabled by default, but I still like to make the second line of any script setlocal EnableExtensions. The first line is @echo off, which is quickly change to rem @echo off until I have finished debugging.

The setlocal EnableExtensions command does two things:

  1. ensures that any environment variables that you set or change within that script will not affect the calling environment.
  2. ensures that Command Extensions are enabled. Command Extensions are good

If you want to impress your friends by writing sophisticated and useful scripts in Batch (a task that at one time was thought to be impossible), read carefully and grock the embedded documentation on each of these commands:

  • if
  • set
  • call
  • for
  • cmd

You will have to utilize every trick and nuance these commands have to offer to write really good scripts.

For example: The set command can be used for many tasks:

  1. Simple assignment:
    set myDir=C:\Foo

  2. Performing math:
    set /a myCount=myCount + 1

  3. Prompting for input:
    set /p myColor=What is favorite color

  4. Extracting substrings:
    set myCentury=%myYear:~0,2%

Here is how I would have written your script

@echo off
setlocal EnableExtensions

if exist "%MyDir%\tmp" (
    echo Folder exists
) else (
    echo Folder does not exist
)

Good luck and happy hunting.

查看更多
登录 后发表回答