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

Stefan Zimmermann zimmermann.code at gmail.com
Thu May 7 05:38:16 EDT 2015


Nice to see that my topic gains that interest :)
And I see that I should have gone more into detail about what I'm actually trying to point out.

Chris Angelico wrote:
> Hmm... hm... Ha! Found the difference. I had an explicit shebang on my
> script; yours just starts out with shell commands. That means that
> your shell script wasn't truly executable, and thus requires a shell
> to execute it. Try adding "#!/bin/sh" to the top and rerun that - at
> that point, it becomes kernel-executable instead of just
> shell-executable.

That's the big advantage of Unix. You can write an kernel-executable script without any file extension, just by putting a shebang to the beginning of that file. And for the caller it makes no difference if 'command' is a binary or a script and Popen('command') works in both cases, without the shell=True overhead.

Steven D'Aprano wrote:
> 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?

On Unix you can shadow any binary with a wrapper script of the same name located in a path appearing earlier in $PATH. Any caller will automatically run your script instead of the original binary. An that's usually seen as a big advantage on Unix.
On Windows executability depends on the file extension and if you want to wrap some command.exe you usually write a command.bat in a path with higher precedence. And in Windows it's standard that .exe, .com, .bat and .cmd files should be callable without writing the file extension.
And as already mentioned, there is a defined precedence order if they are in the same directory.
That's not more or less security risky as shadowing binaries with scripts on Unix.

My point is that compared to Unix it's just a big disadvantage on Windows that the subprocess.Popen(['command']) can only call command.exe implicitly, which makes it impossible to work with custom wrapper .bat or .cmd scripts without the shell=True overhead.
And this is acutally confusing for a Windows user.
You write a wrapper .bat for some .exe and are wondering why your Python script doesn't use it.

And the FindExecutable() function from the win32 API would just be the perfect solution for implementing this.



More information about the Python-list mailing list