Today I wanted to write a script that I could execute from both *nix (using Bash or a similar shell) and on Windows (from a command prompt, i.e. a batch file). I found Max Norin’s solution which works, but has a few limitations, e.g. when run it outputs either the word “off” when run in *nix or the word “goto” when run on Windows. There’s got to be a sneaky solution, right?
Here’s my improved version:
Mine exploits the fact that batch files can prefix commands with
@ to suppress outputting them as they execute. So
@goto can be a valid function name in
zsh etc. but is interpreted as a literal
goto command in a Windows Command Prompt. This allows me to move the
echo off command – which only has meaning to Windows – into the Windows section of the script and suppress it with
The file above can be saved as e.g.
myfile.cmd and will execute in a Windows Command Prompt (or in MS-DOS) or your favourite *nix OS. Works in MacOS/BSD too, although obviously any more-sophisticated script is going to have to start working around the differences between GNU and non-GNU versions of core utilities, which is always a bit of a pain! Won’t work in
sh because you can’t define functions like that.
But the short of it is you can run this on a stock *nix OS and get:
$ ./myfile.cmd GNU/Linux
And you can run it on Windows and get:
> .\myfile.cmd Windows_NT
You can’t put a shebang at the top because Windows hates it, but there might be a solution using PowerShell scripts (which use hashes for comments: that’s worth thinking about!). In any case: if the interpreter strictly matters you’ll probably want to shell to it on line 3 with e.g.
Why would you want such a thing? I’m not sure. But there is is, if you do.