Work around subprocess.call() issue on Windows #220
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
On POSIX-like systems, calling
subprocess.call()
with bothshell=True
andexecutable='...'
has the following behavior:(via https://docs.python.org/3/library/subprocess.html?highlight=subprocess#popen-constructor)
This seems to have a similar behavior on Windows, but this is problematic when a POSIX shell is substituted for cmd.exe. This is because when
shell=True
, the shell is invoked with a '/c' argument, which is the correct argument for cmd.exe but not for Bash, which expects a '-c' argument instead. See here: https://github.com/python/cpython/blob/1def7754b7a41fe57efafaf5eff24cfa15353444/Lib/subprocess.py#L1407This is problematic when combined with Dotbot's behavior, where the
executable
argument is set based on$SHELL
. For example, when running in Git Bash, the$SHELL
environment variable is set to Bash, so any commands run by Dotbot will fail (because it'll invoke Bash with a '/c' argument).This behavior of setting the
executable
argument based on$SHELL
was introduced in 7593d8c. This is the desired behavior. See discussion in #97 and #100.Unfortunately, this doesn't work quite right on Windows. This patch works around the issue by avoiding setting the
executable
argument when the platform is Windows, which is tested usingplatform.system() == 'Windows'
. This means that shell commands executed by Dotbot on this platform will always be run using cmd.exe. Invocations of single programs or simple commands will probably work just fine in cmd.exe. If Bash-like behavior is desired, the user will have to write their command asbash -c '...'
.This shouldn't have any implications for backwards-compatibility, because setting the
executable
argument on Windows didn't do the right thing anyways. Previous workarounds that users had should continue to work with the new code.When using Python from CYGWIN,
platform.system()
returns something like 'CYGWIN_NT-...', so it won't be detected with the check, but this is the correct behavior, because CYGWIN Python'ssubprocess.call()
has the POSIX-like behavior.This patch also refactors the code to factor out the
subprocess.call()
, which was being called in bothlink.py
andshell.py
, so the workaround can be applied in a single place.See the following issues/pull requests for a discussion of this bug:
An issue has also been raised in Python's issue tracker:
Thanks to @shivapoudel for originally reporting the issue, @SuJiKiNen for debugging it and submitting a pull request, and @mohkale for suggesting factoring out the code so that other plugins could use it.