Why don’t any commands work after I run my batch file? I’m told that they are not recognized as an internal or external command, operable program, or batch file.


I sort of forgot to celebrate CLR Week last year, so let's say that CLR week is "on hiatus" until next year. To fill the summertime time slot, I'm going to burn off a busted pilot: This week is Batch File Week 2012. Remember, nobody actually enjoys batch programming. It's just something you have to put up with in order to get something done. Batch programming is the COBOL of Windows. (Who knows, if people actually like Batch File Week [fat chance], maybe it'll come back as a regular series.)

We'll open Batch File Week with a simple puzzle.

A customer reported that after running their batch file, almost no commands worked any more!

C:\> awesomebatchfile.bat
... awesome batch file does its work ...

C:\> reg query "HKLM\Software\Clients\Mail" /ve
'reg' is not recognized as an internal or external command,
operable program or batch file.

Wha? Maybe I can run regedit.

C:\> regedit
'regedit' is not recognized as an internal or external command,
operable program or batch file.

OMG OMG OMG OMG.

C:\> notepad
'notepad' is not recognized as an internal or external command,
operable program or batch file.

Okay, first, sit down and take a deep breath. Maybe take a Chill Pill.

My first question was "Does awesomebatchfile.bat modify the PATH variable?" (This was, strictly speaking, a psychic debugging question, but a rather obvious one.)

The customer replied, "Nope. Here, I'll send you the whole thing."

And there it was, right there at the top of awesomebatchfile.bat:

set path=C:\awesomedir
if NOT "%1"=="" set path=%1
cd /d %path%
echo Awesomeness commencing in the %path% directory!
...

The customer figured it would be convenient to have a variable called path, unaware that this variable has special meaning to the command interpreter. The customer didn't make the connection that their seemingly private variable called path was connected to the system variable of the same name (but by convention capitalized as PATH).

Comments (30)
  1. John says:

    I'm not saying batch programming is the worst thing in the world, but I can't think of a way to finish that sentence.

  2. Brian_EE says:

    Maybe he/she could have used COMSPEC instead…

  3. Evan says:

    Here's a fun puzzle. I once had an installer "kill" my %PATH% as set in the registry. When I tried to run commands that are found in, say, %systemroot%, it didn't work. Here's a partial command prompt transcript:

    C:>ftp

    'ftp' is not recognized as an internal or external command, operable program or batch file.

    C:>c:windowssystem32ftp

    ftp> (bye)

    C:>echo %path%

    (the program I just installed that added itself to the path);%SystemRoot%system32;%SystemRoot%;%SystemRoot%System32Wbem;…

    C:>echo %systemroot%

    C:Windows

    [That's a good one. -Raymond]
  4. Evan says:

    BTW, I figured out the problem in collaboration with a friend; I just post it for discussion and amusement value.

  5. J says:

    In Unix, environment variables only apply to a particular process and potentially its children if the variable is exported. As such, you can't run a shell script that modifies PATH, or any other variable, in the shell that launched the script. Why does Windows allow for modification of variables in this way? It seems a bit dangerous.

    [They do affect the parent shell if you run them with ., which for compatibility reasons is the default for the command processor. (Otherwise, autoexec.bat and all the other "set my environment for me" batch files would stop working!) -Raymond]
  6. Grzechooo says:

    I think the remedy to this may be prefixing batch variables with _, just for the sake of not colliding with anything.

  7. Dan Bugglin says:

    J: This feature is suppored but as Raymond says it's opt-in for legacy compatibility reasons.

    You use the "setlocal" command to preserve environment variables so they will be restored on batch file exit.

    "setlocal enableextensions" is what I use.

    Also when I made a batch file for the first time since MSDOS I discovered parenthesis can be used for command grouping with FOR and IF commands, which makes me happy.

    Evan: Adding it to the registry is apparently the proper thing to do: msdn.microsoft.com/…/ms682653(v=vs.85).aspx

    But you have to remember to broadcast the WM message!  I made a program that does it the "right way" and it works just great.

    Lots of legacy installers expected you to drop whatever you were doing and restart the PC after the install (thankfully not too many do that unnecessarily nowadays) so the devs of whatever program that was probably didn't notice it or thought it was an MS bug or something dumb like that.

  8. Evan says:

    @The MAZZTer:

    Adding it there is the right thing to do, but they did it wrong.

    [ANSWER] The type of the PATH environment variable in the registry is normally REG_EXPAND_SZ, so that the %systemroot% and such entries get expanded properly when the value of PATH is fetched. However, the installer replaced the key (value? subkey? I forget my terminology) with one just of type REG_SZ. The PATH isn't expanded further apparently, which meant that it was actually looking in "%systemroot%system32" for software.

  9. Phillip says:

    The MAZZTer, You will be happy with the parenthesis being used for grouping until you see what happens when you try to manipulate files/paths with parenthesis in them.

    if something (

    set path=%path%;newfolder

    )

    this has issues if the path has a 'program files (x86)' in the original path somewhere.

  10. Really Maurits? You prefer Perl over PowerShell? Have you gone insane? ;)

    If it were Python I could perhaps somewhat understand, but for typical shell scripting tasks (the kind of thing that you would normally do in batch files or bash scripts in Unix) it's pretty hard to beat PowerShell. For anyone here who has never used PowerShell, I strongly recommend checking it out. :)

  11. frymaster says:

    @sven:

    speaking as a total python fanboy, it's not good for typical shell scripting tasks.  There's a few too many layers of indirection to be able to copy/rename files etc.

  12. Kevin says:

    @Maurits: Does Cygwin's bash terminal count as something "you're willing to install yourself"?

  13. xpclient says:

    Thankfully he didn't use setx. There should be a "Restore default environment variables" feature in Windows when they get screwed up.

  14. Joshua says:

    @Sven Groot. I think MS is the one who's gone insane. Killing SFU because [it is failing in the market because] Cygwin is roundly trouncing them — ok. Making the environment increasingly hostile to Cygwin with every Windows version — not ok because SFU is dead.

  15. Jeff Davis says:

    I enjoy it; I do it from time to time; I take pride in knowing the subtle nuances of for; and I look forward to Batch Week.

  16. @Sven Groot: I don't know, I've never written any significant amount of PowerShell.

  17. Tim says:

    @Evan Good puzzle. I especially liked the subtle clue.

  18. Miff says:

    I'd love a batch file week personally.

    Also, I did the exact same thing under UNIX before, except since the parent shell isn't modified, it was harder to tell what was going on.

  19. Raphael says:

    Batch programming became at least *tolerable* with WinNT 5+'s extensions. (I don't have an NT 3 or 4 lying around, so maybe those were there earlier)

  20. Cesar says:

    Well, to be fair, they were modifying %path%, not %PATH%. Not everyone knows Windows is not case-sensitive. Someone coming from Unix could easily make that mistake.

    The same with sourcing versus calling ("source" or "." versus nothing on Unix, and nothing versus "CALL" on Windows). The default is the opposite of what you would get on Unix (when called without anything special, Unix defaults to spawning a subshell, while Windows defaults to sourcing the script), and the Windows default is confusing (the effects are different if the command you are running comes from an executable or a batch file).

    A question for the Windows people: is there a better interpreter installed by default on all current Windows versions (that is, XP and above)? I believe you get some Visual Basic thing by default on the older versions, and perhaps there is some PowerShell thing by default on newer versions, but is there anything people can count on being installed by default for *any* current and future supported Windows version (except the most minimal installs of Windows Server, where everything missing unless explicitly installed is expected)?

  21. James says:

    I'm looking forward to Batch File Week as well!

  22. Anonymous Coward says:

    The only way this could have been worse is if Path, path and PATH were all different variables, all set to a different value and each required for the correct operation of your computer.

  23. <– would love a Batch File Week

    I infer that the awesome batch file did not itself call anything but native commands and things that lived in c:awesomedir

    @cesar: the hierarchy of script languages installed by default for "any" current and future supported Windows version (though "any" is a strong word) is:

    * Batch files

    * WScript (cscript.exe or wscript.exe)

    * PowerShell

    * Anything you're willing to install yourself (for me it's Perl)

  24. @Sven – I'd like to move to PowerShell, but 4NT is just so much more powerful for me…

  25. Antonio Rodríguez says:

    I like the idea of a Batch File Week. Many of us write (and sometimes enjoy doing so!) batch files and even small commands or wrappers to ease and automate our work. Learning little tricks may be useful, and is surely fun.

    About the PowerShell, on the paper it looks awesome. But IMHO, when you try to actually use it as your command line interpreter, it falls apart. That's because it negates the main virtue of traditional shell scripts: its simplicity. For more complex things, many of us are programmers and can write external tools in C/C#/VB/whatever. Or at least, we can google for an already made one: there are tons of them.

  26. Matt says:

    @xpclient

    That would be a feature which restored your computer to an inconsistent state (because programs you installed likely didn't expect their additions to %path% to get wiped out)

  27. xpclient says:

    @Matt, system paths reset to defaults is better than some installed program paths broken. Programs can always use app paths.

  28. cheong00 says:

    @xpclient: FYI, GlassFish (JSP Application server from Oracle) uses "path" in multiple folders. Try debugging startup problem on that one.

  29. woods says:

    screw COBOL, I love the idea of Batch File Week, keep'em coming!

  30. Matt says:

    @xpclient

    >> "@Matt, system paths reset to defaults is better than some installed program paths broken. Programs can always use app paths."

    Changing the path variable for programs that set it will cause them to break. It's better to reinstall them from a clean state. Thankfully Windows8 comes with a "wipe all of my settings and programs" so this problem will be fixable by your grandma who doesn't know what a path variable is.

Comments are closed.