Four years ago I blogged about an incantation that would allow the Windows command interpreter (cmd) to execute Unix shell scripts written inside plain batch files. Time for an update.
The original trick I posted involved starting the shell script with the line
@#!sh %0.bat %* 2>nul
What we need in order to have a Windows command interpreter batch file (a file with a .BAT suffix) executed through the Unix shell is a Windows command that pass the file as an argument to the Unix shell. The following code will do this trick for its first argument.
@echo off
if "%~$PATH:1"=="" (
rem Not found in PATH; try to run it as specified using the current
rem directory or an absolute path
sh %1 %2 %3 %4 %5 %6 %7 %8 %9
) else (
rem Run the script from the path
sh %~$PATH:1 %2 %3 %4 %5 %6 %7 %8 %9
)
We then need a polyglot command to invoke the above code: a line that will be valid both in the Windows command interpreter and the Unix shell, because both will execute our file's first line. A polyglot program is one that is simultaneously valid in more than one programming language. Such programs have a long history as interesting curiosities. For instance, the following code by Jack Applin, which won in the 1986 International Obfuscated C Code Contest, is portable to the C and Fortran 77 compilers as well as executable by the Unix Bourne shell.
cat =13 /*/ >/dev/null 2>&1; echo "Hello, world!"; exit
*
* This program works under cc, f77, and /bin/sh.
*
*/; main() {
write(
cat-~-cat
/*,'(
*/
,"Hello, world!"
,
cat); putchar(~-~-~-cat); } /*
,)')
end
*/
In our case starting a batch / shell script file with the following polyglot line does the trick.
@#!sh %0.bat %*
#!sh.bat
with
these contents.
(Download the file by right-clicking on the link;
note that the file name starts with #!
).
@#!sh
.#!sh.bat
passing to it as an argument
the location of the script and the remaining arguments.
When the Unix shell reads the line, it will invoke the command
@#!sh
, which, as an empty file, does nothing.
The rest of the file will then be executed as a shell script.
Because Windows batch files don't nest the batch file
#!sh.bat
will never return to execute the rest of the shell
script.
Comments
Toot!
Tweet
Last modified: Tuesday, January 12, 2010 6:52 pm
Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.