::set - { @goto start [Richard Suchenwirth] - In [exec magic], it was explained how a script can be understood both by a Unix shell (which starts tclsh with itself) and Tcl. Here's my version of how to achieve the same with MS-DOS batch files. The first line (up above) is the first trick - to DOS it's an acceptable label because of the leading colon (:), so it proceeds to the '':start'' label (you can omit that section, it's only to document it in Wiki style ;-) The commands after that turn off the echoing of command input and possibly complete the filename with the .bat extension. But you still have to call this script with relative path name - BAT files are searched on PATH but don't tell you where they were found. Then tclsh is called with the name of the script and up to 9 arguments, which you may group in DOS with double quotes if they contain whitespace or are empty strings, and after that control is transfered to the again fancily named label "end of BAT file", where the script ends without terminating its caller (which DOS's ''exit'' would do). To Tcl, the global [set] command assigns the content of the braces to the variable "-" which is [unset] immediately after. From that line, your "payload" code may begin. In it, you may refer to environment variables that were set in the DOS part of the script - e.g ::env(script) or ::env(SCRIPT) (case doesn't matter that much for DOS) also contains the script's file name. Finally, the label "end of BAT file" is hidden to Tcl by prolonging the preceding comment by the trailing backslash (which must not be omitted, like in [exec magic]). For a linguist, twisting a single source file so that three very diverse languages (DOS-BAT, Tcl, and WikiML) understand it each in their own way, makes a small but entertaining weekend fun project...enjoy! ---- :start @echo off set script=%0 if exist %script%.bat set script=%script%.bat tclsh %script% %1 %2 %3 %4 %5 %6 %7 %8 %9 goto end of BAT file };unset - ;#-------------------------------begin "payload" Tcl puts "Hello, DOS, time now is" puts [clock format [clock seconds]] gets stdin line ;# just to test puts [string toupper $line] puts [list argc: $argc argv: $argv] #------------------------------------------end Tcl\ :end of BAT file ---- My god, Richard. You have brought back long supressed memories of multi-hundred line DOS batch files... -''PSE'' [Robert Abitbol] Good stuff never gets suppressed from one's memory! It just remains and comes back one day when it is needed! ---- [KPV] The folklore idiom for this is below. Don't remember where I first saw it--I couldn't find it in the FAQ just now--but it's been around for a while. This is fairly barebones and doesn't handle the missing ''.bat'' extension: if your using 4Dos you can replace ''%0'' with ''%@search[[%0]]'', otherwise you can use [RS]'s ''if exist...'' logic from above. ::catch {};#\ @tclsh.exe %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 ::catch {};#\ @goto eof ---- [Robert Abitbol] For me you have brought the realization that some things work great and are tremendously useful like Dos batch files. Microsoft was clever enough to keep them aroud. I just wish they could do more like ope a file; show files in a sub-directory etc. If you can figure that one out, Richard, write a book and you'll be a rich man! You'd be surprised at the number of people who still use Dos nowadays! And some of them are pretty young! Richard, what does the batch file on top do anyway? - [RS]: It does what is between "payload" and "end Tcl" - up to "end of BAT file" it is one file. --- [Randolf Schultz] Does the automatic .bat extension addition work on WinXP? I think no, because on WinXP %0 is always replaced with quotes, so that the "if exists"-line above does in fact (on WinXP) the following: if exists "myscript".bat set script="myscript".bat Could someone with XP please try and comment, I am not sure, whether this really affects the if exists... If it does not work, http://www.ayam3d.org/ayam.bat has some additional magic to cure this (use %~0). --- [Randolf Schultz] What happens if the script is located in a path with spaces, like e.g. "Documents and Preferences"? There should be quotes around the %script% in the tclsh call (and perhaps around the %1 too, in case our script is not called manually, but via drag and drop, which in turn may not add quotes...). [DKF]: Something like this might also be workable. ::if 0 { @tclsh.exe %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 @goto eof } --- MNP: Here's the Tcl version of the DOS part of the results of perl2bat. However, thanks Donal because your use of 'goto :eof' improves upon their version yielding: ::if 0 {--*-tcl-*-- @echo off if "%OS%" == "Windows_NT" goto WinNT tclsh "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 goto :eof :WinNT tclsh %0 %* if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto :eof if %errorlevel% == 9009 echo You do not have Tclsh in your PATH. if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul goto :eof } # start Tcl code here Tested on Windows XP SP2 only.