This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author anishathalye
Recipients anishathalye, paul.moore, steve.dower, tim.golden, zach.ware
Date 2020-05-01.13:34:16
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1588340057.85.0.281023369912.issue40467@roundup.psfhosted.org>
In-reply-to
Content
On Windows, using subprocess.call() and specifying both shell=True and the
executable='...' keyword arguments produces an undesirable result when the
specified shell is a POSIX-like shell rather than the standard cmd.exe.

I think the documentation is unclear on the semantics of Popen() when both
shell=True and executable= are specified on Windows. It does say the following
about POSIX systems:

> If shell=True, on POSIX the executable argument specifies a replacement shell
> for the default /bin/sh.

But the documentation doesn't say anything about Windows in this scenario, so
I'm not sure if this is a bug, or if it's undefined behavior.

Concretely, here's an example program that fails due to this:

    import subprocess
    bash = 'C:\\Program Files\\Git\\usr\\bin\\bash.exe'
    subprocess.call('f() { echo test; }; f', shell=True, executable=bash)

It prints out this mysterious-looking error:

    /c: /c: Is a directory

Tracing this into subprocess.py, it looks like it's because the executable bash
(as specified) is being called with the argv that's approximately ['cmd.exe',
'/c', 'f() { echo test; }; f'] (and the program being launched is indeed bash).

Bash doesn't expect a '/c' argument, it wants a '-c' there.

The problematic code in subprocess.py is here:
https://github.com/python/cpython/blob/1def7754b7a41fe57efafaf5eff24cfa15353444/Lib/subprocess.py#L1407
If the '/c' is replaced with a '-c', the example program above works (bash
doesn't seem to care that it's called with an argv[0] that doesn't make sense,
though presumably that should be fixed too).

I'm not sure how this could be fixed. It's unclear when '/c' should be used, as
opposed to '-c'. Doing it based on the contents of the executable= argument or
the SHELL environment variable or COMSPEC might be fragile? I couldn't find
much about this online, but I did find one project (in Ruby) that seems to have
run into a similar problem. See
https://github.com/kimmobrunfeldt/chokidar-cli/issues/15 and
https://github.com/kimmobrunfeldt/chokidar-cli/pull/16.

At the very least, even if this isn't fixed / can't be fixed, it might be nice
if it's possible to give some sort of useful warning/error when this happens --
perhaps say that specifying both shell=True and executable="..." isn't
supported on Windows?

I ran into this issue while while debugging an issue in a project of mine. In
case the additional context is useful, here is the discussion:
https://github.com/anishathalye/dotbot/issues/219
History
Date User Action Args
2020-05-01 13:34:17anishathalyesetrecipients: + anishathalye, paul.moore, tim.golden, zach.ware, steve.dower
2020-05-01 13:34:17anishathalyesetmessageid: <1588340057.85.0.281023369912.issue40467@roundup.psfhosted.org>
2020-05-01 13:34:17anishathalyelinkissue40467 messages
2020-05-01 13:34:16anishathalyecreate