`M-x term' with Emacs on MS Windows: error Spawning child process: invalid argument

孤人 提交于 2019-11-29 09:46:57

From my experience none of the terminal emulators in Emacs (term, ansi-term, multi-term) is supported under Windows. It looks like the main reason is all of them rely on low-level support for terminals (stty, etc) which is not provided by Windows. Trying to force Emacs to use, say, Cygwin bash by editing references to e.g. /bin/sh in term.el doesn't help either. It may work in Cygwin Emacs but I haven't used it in a long time because native W32 Emacs is so much better (for me). Shell mode works fine with either Cygwin bash or Windows cmd (via cmdproxy which is part of Emacs install). You can have support for ANSI colors if you do

(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)

I tried eshell many times but ended up using the shell mode with bash because I tend to use pipes and redirections a lot. Are there any particular applications that you would like to use that require full-featured terminal support? I was missing top at first but then I just started using M-x proced.

UPDATE: term, ansi-term, and multi-term do work in Cygwin emacs.

This is an attempt to record a more general answer about the message "Spawning child process: invalid argument", which emacs produces in various situations. I am using emacs 25.0.50.1 on Windows 7, but I have looked into this before with earlier versions and I do not think that anything relevant has changed. For some reason, this error does not start the debugger even if debug-on-error is set. However, it seems that the error is always generated by the function start-process in subr.el (in the top lisp directory). You can therefore enter M-x debug-on-entry RET start-process RET, and then do whatever it is that caused the error. Emacs will then show a backtrace buffer, the second line of which will show the arguments passed to start-process. The last argument is supposed to be the name of an executable file. In all cases where I have seen the "Spawning child process: invalid argument" error, the executable file did not actually exist. You then need to work out where emacs got the filename from, and how to change it. You can get some clues from the rest of the backtrace buffer.

In the case of the M-x term command, the executable file used is the first of the following things that has a non-nil value:

  • The lisp variable explicit-shell-file-name (which you can customize after entering C-h v RET explicit-shell-file-name RET)
  • The environment variable ESHELL
  • The environment variable SHELL
  • The hardcoded value /bin/sh

(You can see this by looking at the code in term.el in the top lisp directory.)

I tried to run M-x termfrom a MingW64 emacs with an MSYS2 bash.exe and I got the same error as you got. It is possible to get a little bit further by changing term-exec-1 in term.el to read:

    (apply 'start-process name buffer
           (getenv "SHELL") "-c"
       (format "stty -nl echo rows %d columns %d sane 2>/dev/null;\
if [ $1 = .. ]; then shift; fi; exec \"$@\""
           term-height term-width)
       ".."
       command "-i" switches)))

You need to answer with the MSYS2 shell path which is something like /usr/bin/bash.exe and then you get a terminal. The problem is that the terminal is messed up. The stty command doesn't work on it and the cr doesn't work. Also, the cd emacs function receives MSYS2 paths like /c/usr/share/emacs/ which are not valid. This function needs to be advised to transform those paths to Windows paths.

Looking in the source code of term.el, I can see a hardcoded "/bin/sh" that is used to launch the program to run (the one that exists in your path). If you can create a copy of your your bash.exe in that exact location and name (I am not sure if Windows cygwin paths allow that), you might get lucky.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!