PEP idea: On Windows, subprocess should implicitly support .bat and .cmd scripts by using FindExecutable from win32 API

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed May 6 23:33:11 EDT 2015


On Thursday 07 May 2015 12:19, Chris Angelico wrote:

> On Thu, May 7, 2015 at 10:58 AM, Dave Angel <davea at davea.name> wrote:
>> There's nothing Windows-specific about that behaviour.  In Linux, there
>> are
>> bash commands that can only be run by using shell=True.  Fortunately
>> Popen didn't make the mistake of pretending it's a shell.
> 
> But bash commands aren't the same as shell scripts. For instance, if
> you want to enumerate bash aliases, you can't exec() to the 'alias'
> command, because there isn't one. But shell scripts *can* be exec'd:

Um, are we still talking about Python here? exec("alias") fails with 
NameError on all the versions of Python I know. *semi-wink*

I'm guessing you're taking about some other exec, it might be a good idea 
that on a Python mailing list you don't assume that we're all going to 
understand the context :-)


> $ grep $ exec_demo.*
> exec_demo.c:#include <stdio.h>
> exec_demo.c:#include <unistd.h>
> exec_demo.c:int main()
> exec_demo.c:{
> exec_demo.c: printf("This part is coming from C code.\n");
> exec_demo.c: int err=execl("./exec_demo.sh", 0);
> exec_demo.c: printf("exec() failed! %d\n",err);
> exec_demo.c:}
> exec_demo.sh:#!/bin/sh
> exec_demo.sh:echo This part ran from the shell.
> exec_demo.sh:echo Hello, world!
> $ ./a.out
> This part is coming from C code.
> This part ran from the shell.
> Hello, world!

> $ pike -e 'Process.exec("./exec_demo.sh");'
> This part ran from the shell.
> Hello, world!

Okay, so C code can call the shell. So can Pike.


> $ python -c 'import subprocess; subprocess.call(["./exec_demo.sh"])'
> This part ran from the shell.
> Hello, world!

And so can Python. I'm not entirely sure what point you are trying to make 
here, or how it relates to the OP's problem that when he calls 

subprocess.Popen(['foo'])

he expects it to run any of foo.exe, foo.cmd, foo.bat (and possibly any 
other number of executable files). Are you agreeing with him or disagreeing?

Apart from any other number of problems, surely having "foo" alone run 
foo.exe, foo.bat etc. is at best confusing and at worst a security risk? 
What if you have *both* foo.exe and foo.bat in the same directory?


> (Python doesn't seem to have any way to 'exec', but a subprocess comes
> to the same thing.)

According to `man exec` on my Linux system, I don't think that is correct. 
The exec* family of functions "replaces the current process image with a new 
process image", they don't run in a subprocess.

I think the Python equivalent of Unix exec* commands are the various 
os.exec* functions.


> I don't know about Windows, but it seems reasonable to be able to be
> able to run many types of program equally, including batch files. But
> maybe Windows is just weak that way.


Hmmm. I'm not sure if this is relevant, or if I'm going off on a tangent, 
but if I write a short bash script and set the execute permission:

steve at runes:~$ chmod u+x test.sh
steve at runes:~$ cat test.sh 
echo "Running shell script"


subprocess.call fails unless I set shell=True:


py> p = subprocess.Popen('./test.sh', shell=True)
py> Running shell script

py> p = subprocess.Popen('./test.sh', shell=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/local/lib/python2.7/subprocess.py", line 1308, in 
_execute_child
    raise child_exception
OSError: [Errno 8] Exec format error


How is this any different from needing to specify shell=True for .bat and 
.cmd files under Windows? This is not a rhetorical question, I actually want 
to know.



-- 
Steve




More information about the Python-list mailing list