New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Git bash cannot execute shell command on login shell #219
Comments
I don't currently have access to a Windows machine, so it's going to be hard for me to replicate and debug. What happens if you use the extended form for the command, and enable stdout/stderr -- do you see a more detailed error message? - shell:
- command: ...
stdout: true
stderr: true |
@anishathalye I receive this error details:
|
Huh, not exactly sure why this is happening. "/c: /c: Is a directory" is a strange error message to see. Maybe it has something to do with how the "~" is evaluated? Does this happen if you run the command manually in a login shell in bash, with the whole |
@anishathalye Can you look in this comment? The same discussion it talked there :) If you need any help to debug through this then let me know. I will help you with the tests in the Windows environment. |
Ok I downloaded a copy of Windows, installed Git Bash and Python, and I was able to reproduce the issue. The issue you linked is indeed related, thank you for that. I think merging #177 will fix the immediate problem, but I don't know if it'll cause collateral damage. I want to understand why the current code doesn't work. The When run in Git Bash, Dotbot calls It seems like >>> bash = 'C:\\Program Files\\Git\\usr\\bin\\bash.exe'
>>> os.path.exists(bash)
True
>>> subprocess.call('echo hi', shell=True)
hi
0
>>> subprocess.call('echo hi', shell=True, executable=bash)
/c: /c: Is a directory
126 Looking at the subprocess.py implementation and tracing it with a The subprocess documentation doesn't really describe the semantics of the
But it doesn't have a similar description for Windows. |
The relevant difference between the login shell and the non-login shell is that the login shell exports
So it runs When
So we run bash, but with its argv set to
What we really want is for
But instead, it does
Bash doesn't care about its On our side, we can work around it by doing something like #177 (not setting I'm not even sure how to reliably detect Windows; e.g. does Update: installed Cygwin and Cygwin's Python; seems like everything works just fine there, so no workaround needed with that. |
@anishathalye In windows, I tried with login shell and displays platform correctly |
On POSIX-like systems, calling `subprocess.call()` with both `shell=True` and `executable='...'` has the following behavior: > If `shell=True`, on POSIX the _executable_ argument specifies a > replacement shell for the default `/bin/sh`. (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#L1407 This 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 using `platform.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 as `bash -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's `subprocess.call()` has the POSIX-like behavior. This patch also refactors the code to factor out the `subprocess.call()`, which was being called in both `link.py` and `shell.py`, so the workaround can be applied in a single place. See the following issues/pull requests for a discussion of this bug: - #170 - #177 - #219 An issue has also been raised in Python's issue tracker: - https://bugs.python.org/issue40467 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.
Moving discussion to #220 |
Thank you for reporting this and helping with debugging. Fixed in #220. |
Make sure the login shell is turned on to replicate this issue. To check use
shopt login_shell
and if it is turned off then usebash --login
and re-check login shell status.Not test the below install shell config accordingly.
With a non-login shell, it's a success but with a login shell, it fails. Here is the logged error:
The text was updated successfully, but these errors were encountered: