Self-executable scripts

To run IronPython scripts on Windows, you have to ask the IronPython interpreter to invoke them. As a result, you always need to type , which can be rather annoying and you have to instruct users of your script to do the same. To make the scripts self-executable so that you can just type the name (even skip the extension) and go, you need to simply do two things:


 * Rename the script extension from  to   or.
 * Make the first line of the script read exactly:

@setlocal enabledelayedexpansion && ipy -x %~f0 %*& exit /b !ERRORLEVEL!

For example, put the following into a file called :

@setlocal enabledelayedexpansion && ipy -x %~f0 %*& exit /b !ERRORLEVEL! import sys args = sys.argv[1:] if args: print 'You said:', ' '.join(args) print 'I say, greetings!'
 * 1) Python code starts from here, second line onwards

Now you can just type  and the script runs!

The way this works is that the whole script is treated like a Windows shell (batch/command) script. The first line invokes the IronPython interpreter, which will be ideally in your, and passes the absolute path to the file  along with all arguments. The  switch tells the interpreter to skip the first line of the script so that it does not trump on it, being illegal Python code. When the interpreter returns,  will make sure that rest of the now-back-to-shell-script is skipped because the Python code makes for illegal shell commands.

Both worlds are hip and happy!

Full Breakdown
Here is a break down of what the first line does:

@setlocal enabledelayedexpansion && ipy -x %~f0 %* & exit /b !ERRORLEVEL!

It is actually three shell script statements compressed into one line because that is all the interpreter affords us. You could almost read it as if it was written as:

setlocal enabledelayedexpansion ipy -x %~f0 %* exit /b !ERRORLEVEL!

The starting  prevents the line itself from being echoed.

The second statement is the simplest to understand. It invokes the IronPython interpreter, telling it to skip the first line via the  switch. The third statement,  prevents the rest of (illegal) shell script from running by exiting immediately. More importantly, however, it propagates the exit code from the Python script out to the caller of the shell script. This is important if the caller is going to use the exit code, the usual practice, as an indicator of success or failure. Upon success (exit code zero), the caller may want carry out further actions like send out an e-mail or delete some files. You don't want that to happen unless the script did, in fact, succeed!

The first statement,, affects how the third one is interpreted. It makes sure that the special  environment variable holding the exit code of the last executed command is expanded when   will be executed, not when the line is read by the command processor, the default behavior with. Had  been used instead, it would have always returned zero as the exit code because that would have been the value of   when the entire first line is read by the command processor. , on the other hand, will use the value in effect after the IronPython interpreter returns.

Note: The same technique can be applied to CPython on Windows using the same  flag.

Back to Contents.