Generate a Windows command file that executes a Python program. Typing 'my_prog arg1 is easier than typing 'python C:\PyLib\my_prog.py arg1'. Needed because Windows does not support '#!/bin/env python' as the first line of the program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
# MkPyCmd.py # Copyright 2005 by James M Jinkins --- Released to the Public Domain. # email address: jim -dot_ jinkins -at_ comports -dot_ com progDoc = r"""MkPyCmd.py generates a command file to execute a Python program. The windows command file will have the same filename as the Python program, but will have a '.cmd' extension instead of '.py.. It will pass its command line arguments to the Python program. Note: usage: python [py_path\]python_program [cmd_path] where py_path Optional path to the python program. Default is the current directory. python_program Python program. Since the extension must be .py, it is not required. cmd_path Optional path to the generated command file. Default is the current directory. Generate it in a directory in the PATH environment variable. The command python C:\PyLib\MkPyCmd.py C:\PyLib\my_prog C:\cmd generates file C:\cmd\my_prog.cmd, which contains this line: python "C:\PyLib\my_prog.py" %* """ import os import sys def displayErrMsgExit(msg = ''): print progDoc if msg: print "\nError: %s" % msg sys.exit(1) if (len(sys.argv) < 2 or sys.argv.lower() == '-h' or sys.argv.lower() == '--help'): displayErrMsgExit() if len(sys.argv) > 3: displayErrMsgExit("Too many command line arguments") pyProgram = sys.argv pyProgPath = os.path.abspath(pyProgram) pyPath, pyFilespec = os.path.split(pyProgPath) pyFilename, pyExt = os.path.splitext(pyFilespec) if pyExt.lower() == '.py': cmdFilespec = pyFilename + '.cmd' else: cmdFilespec = pyFilespec + '.cmd' pyProgPath += '.py' if not os.path.isfile(pyProgPath): displayErrMsgExit("python_program file '%s' not found" % pyProgramPath) if len(sys.argv) > 2: if not os.path.isdir(sys.argv): displayErrMsgExit("cmd_path arg '%s' is not a directory" % sys.argv) cmdPath = os.path.join(sys.argv, cmdFilespec) else: cmdPath = cmdFilespec f = open(cmdPath, 'w') print >>f, 'python "%s" %%*' % pyProgPath f.close()
When I write a Python program command with a command-line interface for my own use on Windows and especially for non-Python-programmers, I usually wrap it in a command file with the same filename. Then, instead of typing python C:\PyLib\my_prog.py arg1 ... I type my_prog arg1 ...
I finally got tired of manually writing each command file and wrote MkPyCmd.py. Then I ran it to generate MkPyCmd.cmd in a directory on the PATH.
Simpler Way? Perhaps I don't fully understand what the purpose or effects of this recipe -- but the best way I've found to accompish something similar is to modify your PATHEXT environment variable to include .py files. Then you can just enter the name of the .py file at the command line (with or without the '.py' extension), and it will treat it as an executable.
On Win XP Pro you can modify the PATHEXT environment variable by clicking the Environment Variables button on the Advanced tab in My Computer's properties dialog (or via the 'System' Control Panel).
Even simpler... I use ActiveState's ActivePython distribution and this is handled automatically for me on Windows by the installation. All I have to do to run a python file called 'something.py' is type 'something' or 'something.py', followed by any other arguments.
I agree but. I agree with you. However, up to my knowledge, there is still some case where a .cmd wrapper could be usefull.
If you plan to redirect the input of your script the pathext trick seems not adequate and the .cmd yes.
is not the same as:
that could be wrapped into:
it is possible to do it MUCH shorter.
and the 2 lines that zope did cut. 3) be sure that python is within your path
Harald Armin Massa
(I do not take credit for this, I googled it up some loooong time ago, pls do not ask where; I assume "unfrequently asked questions")
Need to add one bit... As written, cmd.exe will run the python script, then continue trying to interpret the rest of the .cmd file as batch commands. To prevent this, use this header instead:
A few notes:
The single ampersand ("&") means that the "exit /b" clause runs no matter what the python script returns as an exit code; the more commonly-used "&&" will not run the exit clause if the python script ends with a nonzero return code.
The /b on exit means "exit the current batchfile"; without /b, the instance of cmd.exe will exit.
correct... Tim, you are more than correct.
added, but I could not get it through the filters :((
I had to add quotes to deal with scripts that are in folder with spaces in they pathname. I'am glad of this receipt it works perfectly redirecting input and output the right way and returning the right return code. Apart from the fact that it isn't platform dependent it is wondefull ;-).
Ahh... I saw that when I previewed my post as well... it's not a question of filters; ASPN's site doesn't properly escape certain characters. If you want an ampersand, you have to escape it yourself, HTML-style, using &