views:

261

answers:

2

I have a batch file that tries to run the program specified in its first line. Similar to Unix's shebang:

C:\> more foo.bat
#!C:\Python27\python.exe
%PYTHON% foo-script.py
C:\>

What I want to know is: is there a way to automatically set %PYTHON% to C:\Python27\python.exe which is specified in the first line of the script following the shebang (#!)?

Background: I am trying to do this so as to explicitly specify the Python interpreter to invoke (as there are multiple Python interpreters installed on the system) in the wrapper script.

Assumption: You can assume that script already knows it's own filename (foo) and %~dp0 is the directory of this script. How do we read the first line excluding the shebang?

Clarification: Adding C:\PythonXY to %PATH% is not a solution. The shebang line is supposed to be modified during install time (the original script is generated on the build machine only) on the user's machine .. which may have multiple Python installations of the same version. And only the shebang line is modifyable (that is how the program works).

+2  A: 

Firstly , on windows, there is no need for shebang. Its best to include the path of the Python interpreter to the PATH environment variable of the user who is running the script. That said, to get the first line in batch, you can use set

set /p var=<file

since you have multiple version of interpreter, why not just use the correct one when you invoke the script?

c:\python27\bin\python.exe myscript.py

Edit:

@echo off
set /p var=<test.py
call %var:~2% test.py

output

C:\test>more test1.py
#!c:\Python26\python.exe

print "hello"


C:\test>more test.bat
@echo off
set /p var=<test1.py
call %var:~2% test1.py

C:\test>test.bat
hello
ghostdog74
For adding to PATH, please see my recently-added clarification in the question.
Sridhar Ratnakumar
Ugh, I just realized that `#!` is not a comment, but invalid syntax in batch file. The entire idea has collapsed.
Sridhar Ratnakumar
However, I can at least use `rem #!<path>`.
Sridhar Ratnakumar
it works fine for me, see my output. show the code you have (in your original post) that gives the error
ghostdog74
@Sridhar: rem #! is Reminder or a comment, anything after rem is ignored...
tommieb75
@ghostdog74: I had the shebang line in the batch file before. So obviously that did not work. But moving the shebang to the Python script is the ideal solution (as you have also edited).
Sridhar Ratnakumar
FYI: I asked this to fix http://mercurial.selenic.com/bts/issue1939 in PyPM .. and here's my final patch: http://gist.github.com/287494 - Thank you for the answer.
Sridhar Ratnakumar
A: 

Shebangs are only native to the filesystems of Unix/Linux/BSD variants, due to their design and layout, the filesystem knows that when a file begins with a shebang, the filesystem triggers the user's terminal process to invoke the shell based on the shebang, usually /bin/sh. This can be confirmed by browsing through the filesystem routines here.

Edit: Have edited my answer to make it fully clear in the context of the Windows environment.

In short this is not possible under Windows (2000 upwards to Windows 7) as the NTFS lacks such a capability to interpret the contents of the data (NTFS does not care what is in the file), and therefore lack the means of having an exec call to load the shebang script, only .EXE, .DLL, .SYS,.DRV's are catered for, but for a script....

Hope this helps, Best regards, Tom.

tommieb75
Note that setuptools/Distribute already uses shebang to emulate exe wrappers on Windows. `foo.exe` invokes the shebang interpreter specified in `foo-script.py`. http://packages.python.org/distribute/setuptools.html#automatic-script-creation
Sridhar Ratnakumar
@tommieb75, the shebang has nothing to do with the filesystem; if you have a script with a shebang saved on a FAT32 or NTFS filesystem, but you execute it from a UNIX variant that can read FAT32 or NTFS, the command will still work -- the key is in how the OS implements "exec" and friends, not the filesystem.
Michael Aaron Safyan
@Michael: to quote your comment 'if you have a script with a shebang saved on a FAT32 or NTFS filesystem, but you execute it from a UNIX variant that can read FAT32 or NTFS, the command will still work' - The twist in your answer!!!! That is implying that it will work under Linux/BSD variant, of course it would work as the NTFS/FAT32 partition would have been mounted and that the fs would know how to deal with shebangs!!! My answer is in the context of and from the Windows environment and ntfs!!!
tommieb75
I think you misunderstood the question. I think the question is more like "knowing that shebang doesn't work on windows, I'm wanting to emulate that using a batch script on windows". As the OP later found out, #!... isn't valid batch file syntax.
Bryan Oakley
Bryan is correct. But even though `#!..` is not a valid batch file sytax, it is valid in the Python script that is being *wrapped*. The batch file will always call the script it is *wrapping* - which script will provide the shebang. This is how Python's setuptools implements its exe wrapper (except it uses binary executables instead of batch files)
Sridhar Ratnakumar