[ Combined Document ] | Contents | Previous | Next
The quoting rules for Windows shells and Cygnus shells have some subtle differences. When Emacs spawns subprocesses, it tries to determine whether the process is a Cygnus program and changes its quoting mechanism appropriately. [Discussion]
Programs that explicitly use a handle to the console ("CON" or "CON:") instead of stdin and stdout cannot be used as subprocesses to Emacs, and they will also not work in shell-mode (the default ftp clients on Windows 95 and NT are examples of such programs - this ftp program is fine for use with ange-ftp, but not for M-x ftp). There is no convenient way for either Emacs or any shell used in shell-mode to redirect the input and output of such processes from the console to input and output pipes. The only workaround is to use a different implementation of the program that does not use the console directly (see the discussion on ange-ftp for a replacement for the default ftp clients).
You may notice that some programs, when run in a shell in shell-mode, have their output buffered (e.g., people have found this happening to them with sql-mode). When the program has a lot of output, it overflows the buffering and gets printed to the shell buffer; however, if the program only outputs a small amount of text, it will remain buffered and won't appear in the shell buffer.
Although it may at first seem like the shell is buffering the output from the program, it is actually the program that is buffering output. The C runtime typically decides how to buffer output based upon whether stdout is bound to a handle to a console window or not. If bound to a console window, output is buffered line by line; if bound to a block device, such as a file, output is buffered block by block.
In a shell buffer, stdout is a pipe handle and so is buffered in blocks. If you would like the buffering behavior of your program to behave differently, the program itself is going to have to be changed; you can use setbuf and setvbuf to manipulate the buffering semantics.
Some programs handle this by having an explicit flag to control their buffering behaviour, typically "-i". Other programs manage to detect that they are running under Emacs, by using getenve("emacs") internally.
A handy solution for Perl scripts is to use:
# Turn all buffering off. select((select(STDOUT), $| = 1)); select((select(STDERR), $| = 1)); select((select(STDIN), $| = 1));
You can run DOS subprocesses under Emacs, with either the native command shell, or one of the alternatives, such as bash, tcsh, or 4NT, instead of command.com/cmd.exe; see the section below on other tools for pointers to other sites.
If you are finding that running 16-bit programs as subprocesses cause your A: drive to be accessed (hanging Emacs until a timeout occurs if no floppy is in the drive), check to see if you have McAfee Virus Shield installed. Users have found that disabling Virus Shield causes the problem to go away. Also, if you have a better fix for this problem, let me know or send mail to the list.
A followup from Bill Carpenter <firstname.lastname@example.org>.
Emacs cannot guarantee that a subprocess gets killed on Windows 95/98, and is a difficult limitation to work around. For the forseeable future, you should always let subprocesses run to completion, including explicitly exiting interactive shells.
If you find that shutting down Windows 95/98 complains that there is a running cmdproxy even though you've exited all programs and it doesn't show up in the Task Manager until you shutdown, this could be a bad interaction with Norton VirusChecker.
Francis Wright has written a nice little package which tries to automatically tell shell buffer(s) to "exit" if you try to kill them, it is called msdos-shell-fix.el, and can be found at : http://centaur.maths.qmw.ac.uk/Emacs/.
When an eof is sent to a subprocess running in an interactive shell via process-send-eof, the shell terminates unexpectedly as if its input were closed. See this description for more info and an example.
You can use an interactive subshell in Emacs by typing "M-x shell". Emacs uses the SHELL configuration variable to determine which program to use as the shell. If you installed Emacs using the addpm.exe program, then addpm.exe will associate the value %COMSPEC% with SHELL in the registry. Emacs will then use the value of the COMSPEC environment variable when it starts up, unless the SHELL environment variable is explicitly defined (as when using the emacs.bat batch file).
If you would like to specify a different shell for Emacs to use, then you should do one of two things. You should either explicitly set the environment variable SHELL to be the shell you want to use, or, if you want to have the COMSPEC environment variable determine the shell, then you need to install Emacs using the addpm.exe program and ensure that the SHELL environment variable is not defined when you start up Emacs.
Any replacement shell should follow Unix convention for the -c option, or else be invoked via cmdproxy.exe if it follows the DOS convention.
Note that sh-script.el does not recognize shell names when they have the '.exe' extension on them. If you use sh-script, you should omit the '.exe' extension when specifying the SHELL variable.
Alternatively, if you do not want to mess with the SHELL or COMSPEC variables, you can explicitly place the following in your startup file:
;; For the interactive shell (setq explicit-shell-file-name "c:/bin/tcsh.exe") ;; For subprocesses invoked via the shell (e.g., "shell -c command") (setq shell-file-name "c:/bin/tcsh.exe")
You can get a version of bash with the Cygnus tools at http://www.cygnus.com/misc/gnu-win32. To use bash with Emacs, place the following in your startup file:
(defun my-shell-setup () "For Cygwin bash under Emacs 20" (setq comint-scroll-show-maximum-output 'this) (setq comint-completion-addsuffix t) ;; (setq comint-process-echoes t) ;; reported that this is no longer needed (setq comint-eol-on-send t) (setq w32-quote-process-args ?\") (make-variable-buffer-local 'comint-completion-addsuffix)) (setq shell-mode-hook 'my-shell-setup)
Richard M. Heiberger's <email@example.com> setup for Cygnus B19.
For more configuration information with bash, take a look at Jonathan Payne's <firstname.lastname@example.org> setup.
If you find that you are having trouble with Emacs tracking drive changes with bash, see Mike Fabian's note <email@example.com>
The package cygwin32-mount.el teaches Emacs about cygwin32 mount points.
WARNING:The latest version of bash sets and uses the environment variable PID. For some as yet unknown reason, if PID is set and Emacs passes it on to bash subshells, bash croaks (Emacs can inherit the PID variable if it's started from a bash shell). If you clear the PID variable in your startup file, you should be able to continue to use bash as your subshell:
(setenv "PID" nil)
For a version of ksh by David Korn, take a look at http://www.research.att.com/sw/tools/uwin. I haven't tried this shell with Emacs, but I'm guessing that it works under Emacs and that you need the following for it to work properly:
(setq w32-quote-process-args t) ; Emacs 20 (setq shell-command-switch "-c")
If you find out otherwise, let me know and I'll update this section.
WARNING: People have reported that UWIN 1.5 ksh doesn't work with Emacs. I do not know why yet. If you figure out why, please send mail to the list.
To use MKS ksh, place the following in your startup file:
(setq w32-quote-process-args t) ; Emacs 20 (setq shell-command-switch "-c")
You can find tcsh at ftp://ftp.blarg.net/users/amol/tcsh. To use tcsh, place the following in your startup file:
(setenv "SHELL" "tcsh.exe") (setq w32-quote-process-args t) ; Emacs 20 (setq shell-command-switch "-cf")
For more configuration information with tcsh, take a look at Chris McMahan's <firstname.lastname@example.org> setup.
You can find zsh at ftp://ftp.blarg.net/users/amol/zsh/
To make dired, (the directory editor), use an external 'ls' program, which will allow you to see symbolic links, and such like you need to set two variables:
(setq ls-lisp-use-insert-directory-program t) ;; use external ls (setq insert-directory-program "c:/cygwin/bin/ls") ;; ls program name ;; Change this to your absolute path --^
Some shells echo the commands that you send to them, and the echoed commands appear in the output buffer. In particular, the default shells, command.com on Windows 95 and cmd.exe on NT, have this behavior.
To prevent echoed commands from being printed, you can place the following in your startup file:
(defun my-comint-init () (setq comint-process-echoes t)) (add-hook 'comint-mode-hook 'my-comint-init)
If shell-mode still is not stripping echoed commands, then you'll have to explicitly tell the shell to not echo commands. You can do this by setting the explicit-SHELL-args variable appropriately, where SHELL is the value of your shell environment variable (do a "M-: (getenv "SHELL")" to see what it is currently set to). Assuming that you are on NT and that your SHELL environment variable is set to cmd.exe, then placing the following in your startup file will tell cmd.exe to not echo commands:
(setq explicit-cmd.exe-args '("/q"))
The comint package will use the value of this variable as an argument to cmd.exe every time it starts up a new shell (as in shell-mode); the /q is the argument to cmd.exe that stops the echoing (in a shell, invoking "cmd /?" will show you all of the command line arguments to cmd.exe).
Note that this variable is case sensitive; if the value of your SHELL environment variable is CMD.EXE instead, then this variable needs to be named explicit-CMD.EXE-args instead.
The character appended to directory names when completing in shell-mode is determined by the value of the variable comint-completion-addsuffix. If the value of this variable it t, then a '/' is appended to directory names. If the value of this variable is a cons pair, then the first value of the pair is appended.
This might happen if, for example, you invoke nmake in a shell and it tries to create subshells. The problem is related to the one above where, again, when the shell is initially created, the first argument to the shell is not the directory in which the shell program resides. When this happens, command.com fabricates a value for its COMSPEC environment variable that is incorrect. Then, when other programs go to use COMSPEC to find the shell, they are given the wrong value.
The fix for this is to either prevent any arguments from being sent to the shell when it starts up (in which case command.com will use a default, and correct, value for COMSPEC), or to have the first argument be the directory in which the shell executable resides.
Chris Boucher <email@example.com> reports that Dr. Solomon's WinGuard prevents any shell related commands from working. He found that turning off "Scan all files" makes it work, though.
[ Combined Document ]
| Contents |
Steve Kemp, FAQ Maintainer
Last Modified : Thursday 1 August 2002