7

I know my title is not descriptive so let me try to explain it here.

Normally I execute my python script like this:

D:\github\Miscellaneous-Programs\Python>python check.py -h
hello
['check.py', '-h']

Now what I did is added the folder D:\github\Miscellaneous-Programs\Python in my windows path environment variable. Than I tried to execute my script like this:

C:\Users\noob>check -h
hello
['D:\\github\\Miscellaneous-Programs\\Python\\check.py']

As you see it didn't showed the -h argument I supplied to it.

My check.py

import sys
print "hello"
print sys.argv

If I remove print sys.argv from the above mentioned python script it work fine in both cases I mentioned above i.e, it prints "hello" just fine.

So, my question is how does one execute a python script that accepts some command line arguments after the script is added to environment variable.

My purpose is to execute my python script from anywhere in the windows command prompt which is somewhat similar to chmod +x check.py.

I tried the chmod option in cygwin it works fine for both cases.

Cygwin output

noob@noob-PC ~
$ chmod +x check.py

noob@noob-PC ~
$ ./check.py h
['./check.py', 'h']
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
RanRag
  • 48,359
  • 38
  • 114
  • 167
  • 2
    make a .bat file containg `python full\path\to\check.py` and add the directory containing that .bat to `Path` (you might want to put `echo off` at the beginning of the .bat. – khachik Apr 23 '12 at 13:43
  • I'd suggest changing the title to something a little more descriptive, eg. "Running a Python script from PATH drops all but the first command-line argument" so other people having the same problem will find it. – mensi Apr 23 '12 at 14:04
  • Was it really `C:\Users\noob>check -h` not `C:\Users\noob>check.py -h`? – Piotr Dobrogost Apr 23 '12 at 18:45
  • Related: [How to execute Python scripts in Windows?](http://stackoverflow.com/questions/1934675/) – Piotr Dobrogost Apr 24 '12 at 20:50

3 Answers3

5

Putting the folder on the PATH does not influence the way the system acts when you run some script by writing script.py -h at the command line. What happens is the system reads the registry to find out how to run the command you gave. You can display this information by first running reg query HKCR\.py /ve and then taking the result (which normally is Python.File) and running reg query HKCR\Python.File\shell\open\command /ve. The output on my system is "C:\Program Files\Python Launcher (64-bit)\py.exe" "%1" %*. This means then when the system sees script.py -h command it runs py.exe program with the first parameter being the name of the script (that's what "%1" means) and the rest of the parameters being the ones given to the script (that's what %*) means. I guess your problem is caused by the lack of %* part in the apropriate registry entry.

Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
  • My output for `regquery`: `(Default) REG_SZ "C:\Python26\python.exe" "%1" %*`. So. it doesn't lack `%*` – RanRag Apr 24 '12 at 01:03
  • This was super helpful for me. – class Feb 27 '14 at 00:40
  • I hadn't had this problem until just recently, but I recently installed Python 3.4 on a new computer with the Python Launcher included and now thanks to this answer discovered that the registry entry for `.py` files (using the file class `py_auto_file`, apparently) was added without the `%*` for some reason. – JAB Apr 10 '14 at 18:55
  • This is the correct answer; I found it useful for getting Anaconda Python working on Windows. It may be easier to do all these changes using the Registry Editor (regedit.exe) running in Administrator mode. – johnwbyrd Jun 24 '17 at 00:50
  • I am stuck finding a solution to this problem. Everything looks as it should but it's resisting to work. There is no py_auto_file and i got the %* -> reg query HKCR\.py /ve ... Python ->reg query HKCR\Python\shell\open\command /ve ...\python.exe" "%1" "%*" – gimba Sep 18 '18 at 07:07
4

Windows does not have a notion of executable script files with the interpreter given as a #!, so what you intend to do cannot work. What Windows does is to call the WinAPI function ShellExecute which does the following:

However, it is more commonly used to launch an application that operates on a particular file. For instance, .txt files can be opened by Microsoft WordPad. The open verb for a .txt file would thus correspond to something like the following command:

"C:\Program Files\Windows NT\Accessories\Wordpad.exe" "%1"

see MSDN

As you can see, only the first parameter is supplied to the application. In your case, this translates to something along the lines of:

"C:\Program Files\Python\Python.exe" "D:\github\Miscellaneous-Programs\Python\check.py"

What you can do to avoid this is to create a little .bat file named check.bat:

python check.py %*

(See this SO question for more details. You might also have to supply an absolute path for check.py or python if they cannot be found)

Community
  • 1
  • 1
mensi
  • 9,580
  • 2
  • 34
  • 43
  • Thanks, for the reply it worked as you suggested. I will acccept your answer just waiting for some other alternative suggestions :D. – RanRag Apr 23 '12 at 13:57
  • *Windows does not have a notion of executable script files with the interpreter given as a #!, so what you intend to do cannot work* Windows doesn't have a notion of shebang indeed but this doesn't mean you can't run various scripts by giving their names on the command line. Btw, there is nice tool which makes shebang work in Windows - [Python Launcher](https://bitbucket.org/vinay.sajip/pylauncher/). – Piotr Dobrogost Apr 23 '12 at 18:50
  • `ShellExecute` is WinAPI function used by the system in the process of executing command like `script.py -h` and without knowing how the system uses this function you can't describe the whole process. Your answer is wrong. – Piotr Dobrogost Apr 23 '12 at 18:58
0

If running from the PATH, you probably don't want to hardcode the script to your python script. So if you place your python script relative to your bat file you could use something like:

@echo off
SET MYPATH=%~dp0
python3.exe %MYPATH%\myscript.py %*