如何在 Emacs 中运行 Cygwin Bash Shell?
Posted
技术标签:
【中文标题】如何在 Emacs 中运行 Cygwin Bash Shell?【英文标题】:How can I run Cygwin Bash Shell from within Emacs? 【发布时间】:2010-09-19 02:43:23 【问题描述】:我在 Windows 上运行 GNU Emacs,所以输入:
M-x shell
启动 Windows 命令行 DOS shell。但是,我希望能够从 Emacs 中运行 Cygwin Bash Shell(或任何其他非 Windows shell)。这怎么可能容易做到?
【问题讨论】:
【参考方案1】:我在 Cygwin 中使用 XEmacs,并且可以相对轻松地从 XEmacs 运行 bash。
这是来自init.el
的相关部分
;; Let's use CYGWIN bash...
;;
(setq binary-process-input t)
(setq w32-quote-process-args ?\")
(setq shell-file-name "bash") ;; or sh if you rename your bash executable to sh.
(setenv "SHELL" shell-file-name)
(setq explicit-shell-file-name shell-file-name)
(setq explicit-sh-args '("-login" "-i"))
【讨论】:
【参考方案2】:shell-file-name
是控制 Emacs 在要运行 shell 命令时使用哪个 shell 的变量。
explicit-shell-file-name
是控制哪个 shell M-x shell
启动的变量。
Ken's answer 改变了这两个,你可能想要也可能不想要。
您还可以通过临时更改explicit-shell-file-name
来创建一个启动不同shell 的函数:
(defun cygwin-shell ()
"Run cygwin bash in shell mode."
(interactive)
(let ((explicit-shell-file-name "C:/cygwin/bin/bash"))
(call-interactively 'shell)))
您可能还希望将 --login
参数传递给 bash,因为您正在启动一个新的 Cygwin 会话。您可以通过设置explicit-bash-args
来做到这一点。 (注意M-x shell
使用explicit-
PROGRAM-args
,其中PROGRAM 是shell 路径名的文件名部分。这就是为什么在设置shell 时不应包含.exe
。
【讨论】:
你的 e-lisp 比我的好 - 我在 几年 前就已经学会了让它按照我想要的方式运行,并且已经忘记了它的大部分含义。我认为我的代码最初是从某处的常见问题解答中复制而来的...... +1,向挥舞括号的尤达大师鞠躬。你的 e-lisp 把我从水里吹出来了。 具体来说,您应该在某处添加 (setq explicit-bash-args '("--login" "-i")) ,否则,我会收到消息“bash: ls: command未找到” 在使用你的函数后你能帮我解决我的 bash 问题吗:***.com/questions/24511224/…? 另一种方法是首先从 cygwin bash 启动 emacs,以便 emacs 具有与 bash 相同的路径。这有点繁琐,但可以通过一些 vbs 脚本来完成。【参考方案3】:您可以直接从 Emacs *shell* 缓冲区中的默认 Windows 命令行 shell 运行 bash:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\temp>bash
bash
但是,没有可见的命令提示符可能会让人迷失方向,从而导致您的命令及其输出结果全部混合在一起。
此外,由于某些未知原因,如果您确实输入了命令并按回车键,则会在命令语句的末尾附加一个回车符 (\r),从而导致 bash 错误:
ls
bash: line 1: $'ls\r': command not found
一种解决方法是在每个命令的末尾手动添加一个注释字符 (#),这样可以有效地删除 \r 文本:
ls #
myfile,txt
foo.bar
anotherfile.txt
这种总体方法远非理想,但如果您想从 Windows 的本机 shell 进入 bash 以执行一些快速操作,然后退出以继续在 Windows 中工作,这可能会很有用。
【讨论】:
【参考方案4】:关于这个主题的一个更重要的提示。
如果您使用 Emacs shell 模式并且有时需要 bash 和 cmd,请将其设置为默认使用 bash,因为您可以在 bash 中键入 cmd 并且生成的 dos shell 工作正常。
如果您将 Emacs 设置为使用 cmd 作为 shell(这是 NT emacs 的安装方式),则 dos shell 可以正常工作,但是如果您键入 bash 或 bash -i 来运行 bash shell,则生成的 shell 不会工作正常 - 见答案 0。
但如果 bash 是 emacs 调用的“第一个”shell,它就可以正常工作。
【讨论】:
【参考方案5】:由于这些方法对我不起作用,我通过以下方式得到它:
(我使用的是 NTEmacs,它默认打开一个 dos shell,所以也许你的 emacs 行为相同)
创建一个名为 SHELL('SHELL' 而不是 '$SHELL')的 windows 环境变量,并为其提供 cygwin 安装的 bash.exe 的路径(例如 c:\programs\cygwin\bin\bash.exe)
现在在执行 M-x shell 时,它会打开一个 bash。
问候,
创新
【讨论】:
我遇到了同样的问题,这也对我有用。我会注意到我必须关闭并重新打开 Emacs 才能使其生效。【参考方案6】:我正在使用 EmacsW32。 C-h a shell$
给出了 shell 启动命令的列表,命令 cmd-shell 和 cygwin-shell 看起来很有趣。这两个命令都需要 EmacsW32。它们也可以在菜单中找到:Tools > W&32 Shells。
如果你是第一次运行 cygwin-shell,如果你没有在 Emacs 中设置 cygwin 路径,它会引导你到自定义页面,你可以通过按 Find 按钮设置 cygwin 路径。
【讨论】:
【参考方案7】:我发现的最佳解决方案如下:
;; 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"))))))
将“--login”作为 cjm suggests 传递的问题是您的 shell 将始终在您的主目录中启动。但是如果你正在编辑一个文件并且你点击了“M-x shell”,你希望你的shell在那个文件的目录中。此外,我已经用“M-x grep”和“M-x compile”测试了这个设置。我怀疑这里的其他示例由于目录和路径问题而无法与这些示例一起使用。
这个 elisp sn-p 属于你的 ~/.emacs 文件。如果您想使用 Cygwin 而不是 MinGW,请将第一个字符串更改为 C:/cygwin/bin/bash。第二个字符串被添加到您的 Windows PATH 之前(在将该 PATH 转换为适当的 unixy 形式之后);在 Cygwin 中,你可能想要 "~/bin:/usr/local/bin:/usr/bin:" 或类似的东西。
【讨论】:
【参考方案8】:除了@Chris Jones 关于避免 bash 的 --login 参数的回答之外,我还设置了以下命令行参数:
(setq explicit-bash-args '("--noediting" "-i"))
--noediting 选项可防止干扰 GNU readline 库,而 -i 选项指定 shell 是交互式的。我还将主目录中的 .emacs_bash 文件用于任何 emacs 特定的 bash 自定义。
【讨论】:
以上是关于如何在 Emacs 中运行 Cygwin Bash Shell?的主要内容,如果未能解决你的问题,请参考以下文章
在 Cygwin 中构建 Emacs 时,目标“自动加载”的配方失败
如何从 Cygwin 在 Jenkins 控制台上显示 bash 脚本执行