blog dds

2006.06.16

Batch Files as Shell Scripts

Although the Unix Bourne shell offers a superb environment for combining existing commands into sophisticated programs, using a Unix shell as an interactive command environment under Windows can be painful.

The problems are numerous: the many commands available as built-ins in the Windows cmd shell are no longer available, network paths and drives behave in quirky ways, and the interaction with the Windows GUI is lacking. Ideally one would like to keep using the Windows cmd shell for interactive sessions, but write scripts using the Unix shell. The same approach is the norm under Unix: we program in sh for its pervasiveness and orthogonality, but use as an interactive shell ksh, csh, or bash.

What we would therefore want is a mechanism for the Windows cmd shell to directly run Unix shell script commands. The Unix command execution environment offers the #! facility for executing scripts under arbitrary interpreters (such as the Bourne shell or Perl), but this is not something that Windows supports. Back in 1990 when I first ported Perl to MS-DOS I came up with the following incantation for running Perl scripts as batch files.

@REM=("
@perl %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
@end ") if 0 ;
Fiteen years later, the Windows shell has only marginally improved, so I found myself searching for a similar incantation to run my Unix shell scripts as batch files.

The solution I came up involves starting each combined batch file / shell script with the following sequence:

@#!sh %0.bat %* 2>nul
For this to work you must have in your path a Unix-compatible shell named sh, and the batch file named #!sh.bat. (Download the file by right-clicking on the link; note that the file name starts with #!).

Thus for example I can convert the tab separated-rows of the Windows clipboard into an HTML table by combinding the Outwit winclip tool together with Perl using the following shell script:

@#!sh %0.bat %* 2>nul
# Convert the clipboard tab separated-rows into an HTML table
winclip -p |
perl -pe '
BEGIN {print "<table>\n"}
END {print "</table>"}
s/^/<tr><td>/;s,\t,</td><td>,g;s,$,</td></tr>,' |
winclip -c

Read and post comments, or share through   


Creative Commons License Last modified: Friday, June 16, 2006 3:58 pm
Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-Share Alike 3.0 Greece License.