Next: , Previous: Printing, Up: Top


7 Subprocesses

7.1 Quoting issues

The quoting rules for native Windows shells and Cygwin shells have some subtle differences. When Emacs spawns subprocesses, it tries to determine whether the process is a Cygwin program and changes its quoting mechanism appropriately. See this previous discussion for details.

7.2 Programs reading input hang

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 client on Windows is an example of such a program - this ftp program is mostly fine for use with ange-ftp or tramp, but not for M-x ftp (see How do I use FTP within Emacs). 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. Microsoft's new

7.3 Buffering in shells and subprocesses

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. The same can happen in other subprocesses that themselves run other programs as subprocesses, for example when using cvs from Emacs, which is itself configured to use ssh, password prompts fail to appear when expected, and cvs appears to hang.

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 for interactive. Other programs manage to detect that they are running under Emacs, by using ‘getenv("emacs")’ internally.

7.3.1 Perl script buffering

A handy solution for Perl scripts to the above problem is to use:

     # Turn all buffering off.
     select((select(STDOUT), $| = 1)[0]);
     select((select(STDERR), $| = 1)[0]);
     select((select(STDIN), $| = 1)[0]);

7.4 16-bit subprocesses accessing the floppy drive

If you are finding the 16 bit DOS subprocesses cause your A: drive to be accessed, hanging Emacs until the read times out if there is no floppy in the drive, check to see if your virus software is causing the problem.

7.5 Killing subprocesses on Windows 95/98/Me

Emacs cannot guarantee that a subprocess gets killed on Windows 95 and its descendants, and it is a difficult limitation to work around. To avoid problems on these systems, you should let subprocesses run to completion including explicitly exiting shells before killing the associated buffer.

If you find that while shutting down, Windows complains that there is a running cmdproxy.exe even though you carefully exited all shells and none were showing in Task Manager before the shutdown, this could be due to buggy interaction with your virus scanner.

7.6 Sending EOF to subprocesses

When an EOF is sent to a subprocess running in an interactive shell with process-send-eof, the shell terminates unexpectedly as if its input was closed. This affects the use of C-c C-d in shell buffers. See this discussion for more details.

7.7 How do I use a shell in Emacs?

You can start an interactive shell in Emacs by typing M-x shell. Emacs uses the SHELL environment variable to determine which program to use as the shell. To instruct Emacs to use a non-default shell, you can either set this environment variable, or customize explicit-shell-file-name. You can also customize shell-file-name to change the shell that will be used by subprocesses that are started with shell-command and related non-interactive shell commands.

7.7.1 bash

Cygwin bash is a popular shell for use with Emacs. To use bash as the default shell in Emacs, you can place the following in your init file:

     (defun my-shell-setup ()
       "For Cygwin bash under Emacs 20"
       (setq comint-scroll-show-maximum-output 'this)
       (make-variable-buffer-local 'comint-completion-addsuffix))
       (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 ?\")
     
     (setq shell-mode-hook 'my-shell-setup)

If you find that you are having trouble with Emacs tracking drive changes with bash, see Mike Fabian's note.

WARNING: Some versions of bash set and use the environment variable PID. For some as yet unknown reason, if PID is set and Emacs passes it on to bash subshells, bash dies (Emacs can inherit the PID variable if it's started from a bash shell). If you clear the PID variable in your init file, you should be able to continue to use bash as your subshell:

         (setenv "PID" nil)

7.8 How do I use Cygwin style paths in Emacs?

The package cygwin-mount.el teaches Emacs about Cygwin mount points.

7.9 How do I make dired use my ls program?

Dired uses an internal lisp implementation of ls by default on Windows. For consistent display of symbolic links and other information with other programs (eg Cygwin) and performance reasons, you may want to use a Windows port of ls instead.

     (setq ls-lisp-use-insert-directory-program t)      ;; use external ls
     (setq insert-directory-program "c:/cygwin/bin/ls") ;; ls program name

7.10 How do I prevent shell commands from being echoed?

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 and cmd.exe, have this behavior.

To prevent echoed commands from being printed, you can place the following in your init 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 init 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; the /q is the argument to cmd.exe that stops the echoing (invoking ‘cmd /?’ in a shell 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.

7.11 How can I make shell completion use forward slashes?

The character appended to directory names when completing in a shell buffer is controlled by the variable comint-completion-addsuffix. See its documentation (with C-h v) for details.

7.12 Why do I get incorrect DOS version messages?

This might happen if, for example, you invoke nmake in a shell and it tries to create sub-shells. The problem happens because 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.

7.13 Why is nothing happening when I enter shell commands?

Some anti-virus software has been reported to cause problems with shells in the past. Try turning off options such as “Scan all files”. See What known problems are there with anti-virus software?.