How to? Shebang, nice idea but am I missing something?

Mar 18, 2010
When I first saw the shebang feature added, I was elated. However, it arrived with a caveat, "Note that EXTPROC and SHEBANG only work with files with a .CMD extension, not .BTM or .BAT."

On my systems, after continuing struggles with CMD.exe, impatience with its quirks, and recoil at the desperate measures people take to write *.bat and *.cmd files that do anything semi-complicated, I settled upon a few simple rules: (1) Write .btm files for anything that is going to need TCC as its interpreter; (2) Try to avoid ever targeting CMD.exe; and (3) set the .bat and .cmd extensions as being handled by CMD.exe (or whatever the system installation default is.) This regimen has worked nicely, shielding me from most of the grief CMD.exe has given me.

Unfortunately, in order to use the shebang feature, it appears I will have to somehow make .cmd files be run by TCC. I fully expect, if I do that, to once again see baroque errors showing up where some quirky CMD.exe behavior has been avoided or accommodated by a similarly quirky batch file which is not understood by TCC in the same way as some past (or present) version of CMD.exe did (or does.) (I do not fault TCC for this. CMD.exe is "designed" by one or more people with twisted minds.)

Today's questions are: Is there some way to use the shebang feature without courting the above-described, all-too-familiar grief? Is there some compelling reason that TCC should only do shebang on .cmd files? Is there any chance of optionally relaxing that pickiness? What is the thinking behind that ".cmd only" restriction?


Staff member
May 14, 2008
The EXTPROC / SHEBANG support is very, very old. (As in 4OS2 old.) It was needed then for CMD compatibility, but I can't think of any reason why it would be necessary nowadays.

Instead of using EXTPROC, why not use executable extensions or one of the scripting languages with native TCC support? (Lua, Python, REXX, Perl, Tcl, etc.)
Mar 18, 2010
I do use executable extensions, quite a bit for scripts using common languages. But there is an overhead involved in setting them up (FTYPE and ASSOC) that makes that convention less attractive for less commonly used programs. The shebang feature puts the relevant information all in one place, without requiring further arrangement (other than having the given interpreter in place.) This is convenient for scripts shared with coworkers.

I find your explanation of the feature's presence surprising. It has been used, extensively, in Unix and Linux systems for decades, long before the OS/2 or Microsoft CLI shell development crew decided to clunkily emulate it. It was that usage, done to good effect, (and by me sometimes), that led to my elation when 4NT got it.

Allowing '#!' to be used in lieu of 'EXTPROC' is a wonderful idea which I thought was taken from the 'Nix convention. That form of shebang (which is a contraction of sharp-bang) could be used in .btm files I would think. After all, that extension is well established.
Mar 18, 2010
(To David re executable extensions being a TCC feature:)

That's a good point, and it softens my disappointment in shebang being less useful than it could be. The beauty of the feature, when it works without funky constraints (on *Nix systems), is that this set of attributes applies:
a. The feature can be used without worry regarding collision with similarly marked files. (Of course, PATH chaos remains.)
b. Scripts can be made useful to others without them having to prearrange recognition and action upon a unique marking.

Executable extensions cannot do this. With that method, there is a fixed relationship between extension and what the ultimate script interpreter will be. With shebang on *Nix systems, there is no relationship required between the filename (of the shebang'ed script) and the ultimate interpreter. They have to be marked 'executable', but having a .cmd (or, almost, a .btm) extension is a palatable substitute on Windows for being marked executable.

Ironically, CMD.exe does not appear to support EXTPROC anymore (on current Windows 10). So the feature appears to be severely orphaned, by CMD.exe because they can never settle on features or get backward compatibility right, and by TCC because (I surmise) it is only a CMD feature begrudgingly ported, in the most limited, CMD-compatible way, to TCC.