Win32: Running python programs from a Cygwin shell

J

Jorgen Grahn

I couldn't think of a good solution, and it's hard to Google for...

I write python command-line programs under Win2k, and I use the bash shell
from Cygwin. I cannot use Cygwin's python package because of a binary
module which has to be compiled with Visual C 6.

My scripts start with a '#!/usr/bin/env python' shebang, as God intended.

Now, I assume I can make cmd.exe run foo.py by asociating *.py with the
python interpreter.

However, if foo.py is in my path and I try to run it from bash, what happens
is:

- bash runs env /cygdrive/h/bin/foo.py
- env runs something like 'python /cygdrive/h/bin/foo.py'
- ... and python (which doesn't know about Cygwin-style paths)
croaks on this, of course

Is there a way around this, which doesn't make my script unusable if I moved
it to a Unix box, or ran it from cmd.exe?

I'd prefer not to write wrapper scripts in perl/bash/BAT...

/Jorgen
 
J

JoeSmith

You could probably write a replacement for env that uses cygpath -m on the
script file. So, your env could call original env then do cygpath -m on the
second paramter. The one thing to think about is what the shell might do to
other file/directory paramters passed to your script. So, does it convert

foo.py .

into:

python /cygdrive/h/bin/foo.py python /cygdrive/h/bin/

Then your python script might not work. So, do you run cygpath on all paramters?

The other option would be to write a special alias/script just for foo.py to
handle on the oddities. This is what I did to get it to execute gvim for
win32. I wrote a shell function to go through all paramters and run cygpath -m
on everything that does not begin with a '-'.

If cygwin normalized everything to the cygpath -m, then I think that the
integration with win32 would be substantially better. So, in the above
scenario, you would have gotten:

python h:/bin/foo.py python h:/bin/

Both cygwin and win32 can handle this. There would be problems when passing to
CMD.exe because it would see the "/"'s and barf. I seem to remember that
therewas some setting to get command.com or cmd.exe to change the switch char.
 
D

David Bolen

JoeSmith said:
You could probably write a replacement for env that uses cygpath -m on
the script file. So, your env could call original env then do cygpath
-m on the second paramter. The one thing to think about is what the
shell might do to other file/directory paramters passed to your
script. So, does it convert

foo.py .

into:

python /cygdrive/h/bin/foo.py python /cygdrive/h/bin/

Then your python script might not work. So, do you run cygpath on all paramters?
(...)
The other option would be to write a special alias/script just for
foo.py to handle on the oddities. This is what I did to get it to
execute gvim for win32. I wrote a shell function to go through all
paramters and run cygpath -m
on everything that does not begin with a '-'.

That sounds very similar to how I have my system setup. I've got bash
functions defined to translate just the first (non-option) argument to
Windows form for use from my bash prompt. I haven't really found it
necessary to process all subsequent arguments (on the rare occasion I
need it I just use `cygpath` myself), and as you point out it might
adversely affect how the commands perceive the input.

I tend to run everything explicitly with "py##" aliases (or python)
from the command line because I bounce between python versions a lot,
so I don't depend on the Windows .py mapping, but presumably a similar
approach could work by an alias for "env".

So for example, my Python relevant section from my .bashrc:

- - - - - - - - - - - - - - - - - - - - - - - - -

#
# Function to pre-process first argument (skipping past options) of a command
# with cygpath to translate paths to for Windows tools.
#
function wpath {
typeset -i cmdstart=1
local cmd=""
local args=""

while arg=${*:$cmdstart:1} && [ "${arg:0:1}" == "-" ]; do
cmdstart=cmdstart+1
done

if [ $# -ge $cmdstart ]; then
cmd=`cygpath -w ${*:$cmdstart:1}`
args=${*:$((cmdstart+1))}
fi

echo ${*:1:$((cmdstart-1))} $cmd $args
}

#
# Function used to execute a command with its first argument translated to
# windows compatible paths.
#
function wcmd {
$1 `wpath ${*:2}`
}

#
# Functions to run explicit Python versions as well as to establish a
# new default path. Automatically use wpath when executing for path names.
#

function py15path
{
export PATH=/c/python/1.5:/c/python/1.5/DLLs:$ORIGPATH
}
function py15
{
PATH=/c/python/1.5:/c/python/1.5/DLLs:$ORIGPATH wcmd python $*
}

function py20path
{
export PATH=/c/python/2.0:/c/python/2.0/DLLs:$ORIGPATH
}
function py20
{
PATH=/c/python/2.0:/c/python/2.0/DLLs:$ORIGPATH wcmd python $*
}

function py21path
{
export PATH=/c/python/2.1:/c/python/2.1/DLLs:$ORIGPATH
}
function py21
{
PATH=/c/python/2.1:/c/python/2.1/DLLs:$ORIGPATH wcmd python $*
}

function py22path
{
export PATH=/c/python/2.2:/c/python/2.2/DLLs:$ORIGPATH
}
function py22
{
PATH=/c/python/2.2:/c/python/2.2/DLLs:$ORIGPATH wcmd python $*
}

function py23path
{
export PATH=/c/python/2.3:/c/python/2.3/DLLs:$ORIGPATH
}
function py23
{
PATH=/c/python/2.3:/c/python/2.3/DLLs:$ORIGPATH wcmd python $*
}

# And establish 'python' to filter through wcmd
alias python='wcmd python'

- - - - - - - - - - - - - - - - - - - - - - - - -


-- David
 
J

Jorgen Grahn

JoeSmith said:
You could probably [...]
[lots of useful stuff snipped]

Thanks to both of you. I'll sit down and go through it again some other
night. I also note that this isn't really a Python issue but a problem
between CygWin and native Win32-applications, so I'd better ask elsewhere
the next time.

BR,
Jorgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top