How can I run Cygwin Bash Shell from within Emacs?

2019-01-08 10:01发布

I am running GNU Emacs on Windows so entering:

M-x shell

launches the Windows command-line DOS shell. However, I would like to instead be able to run the Cygwin Bash Shell (or any other non-Windows shell) from within Emacs. How can this be easily done?

8条回答
疯言疯语
2楼-- · 2019-01-08 10:27

I'm using EmacsW32. C-h a shell$ gives a list of shell launching commands and the commands cmd-shell and cygwin-shell look interesting. Both commands need EmacsW32. They are also found in the menu: Tools > W&32 Shells.

If you run cygwin-shell for the first time, and if you have not setup cygwin path in Emacs, it leads you to the Customization page where you can setup the cygwin path by pressing Find button.

查看更多
混吃等死
3楼-- · 2019-01-08 10:29

shell-file-name is the variable that controls which shell Emacs uses when it wants to run a shell command.

explicit-shell-file-name is the variable that controls which shell M-x shell starts up.

Ken's answer changes both of those, which you may or may not want.

You can also have a function that starts a different shell by temporarily changing explicit-shell-file-name:

(defun cygwin-shell ()
  "Run cygwin bash in shell mode."
  (interactive)
  (let ((explicit-shell-file-name "C:/cygwin/bin/bash"))
    (call-interactively 'shell)))

You will probably also want to pass the --login argument to bash, because you're starting a new Cygwin session. You can do that by setting explicit-bash-args. (Note that M-x shell uses explicit-PROGRAM-args, where PROGRAM is the filename part of the shell's pathname. This is why you should not include the .exe when setting the shell.

查看更多
Bombasti
4楼-- · 2019-01-08 10:35

You can run bash directly from the default Windows command-line shell within your Emacs *shell* buffer:

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\temp>bash
bash     

However, no command prompt is visible which can be disorienting resulting in your commands and their output results all blending together.

In addition, for some unknown reason, if you do enter a command and hit return, a return line character (\r) is appended to the end of your command statement causing a bash error:

ls
bash: line 1: $'ls\r': command not found

A workaround is to manually add a comment character (#) at the end of every command which effectively comments out the \r text:

ls #
myfile,txt
foo.bar
anotherfile.txt

This overall approach is far from ideal but might be useful if you want to drop into bash from Windows' native shell to do some quick operations and then exit out to continue working in Windows.

查看更多
我想做一个坏孩纸
5楼-- · 2019-01-08 10:36

In addition to @Chris Jones' answer about avoiding the --login argument to bash, I set the following command line arguments:

 (setq explicit-bash-args '("--noediting" "-i"))

The --noediting option prevents interference with the GNU readline library and the -i option specifies that the shell is interactive. I also use the .emacs_bash file in my home directory for any emacs specific bash customizations.

查看更多
三岁会撩人
6楼-- · 2019-01-08 10:40

Since these approaches didn't work for me I got it the following way:

(I'm using NTEmacs which opens a dos shell by default, so perhaps your emacs behaves the same)

Create a windows environment variable named SHELL ('SHELL' not '$SHELL') and give it the path to bash.exe of your cygwin installation (for example c:\programs\cygwin\bin\bash.exe)

Now when doing M-x shell it opens a bash.

Regards,

Inno

查看更多
仙女界的扛把子
7楼-- · 2019-01-08 10:45

The best solution I've found to this is the following:

;; When running in Windows, we want to use an alternate shell so we
;; can be more unixy.
(setq shell-file-name "C:/MinGW/msys/1.0/bin/bash")
(setq explicit-shell-file-name shell-file-name)
(setenv "PATH"
    (concat ".:/usr/local/bin:/mingw/bin:/bin:"
        (replace-regexp-in-string " " "\\\\ "
            (replace-regexp-in-string "\\\\" "/"
                (replace-regexp-in-string "\\([A-Za-z]\\):" "/\\1"
                    (getenv "PATH"))))))

The problem with passing "--login" as cjm suggests is your shell will always start in your home directory. But if you're editing a file and you hit "M-x shell", you want your shell in that file's directory. Furthermore, I've tested this setup with "M-x grep" and "M-x compile". I'm suspicious that other examples here wouldn't work with those due to directory and PATH problems.

This elisp snippet belongs in your ~/.emacs file. If you want to use Cygwin instead of MinGW, change the first string to C:/cygwin/bin/bash. The second string is prepended to your Windows PATH (after converting that PATH to an appropriately unixy form); in Cygwin you probably want "~/bin:/usr/local/bin:/usr/bin:" or something similar.

查看更多
登录 后发表回答