zsh和emacs的(e)shell之间的优缺点

35

我最近转向使用Emacs(Aquamacs),正在逐步将我的整个工作流迁移到其中(从Pathfinder、Notational Velocity等到Org-mode、Dired等)。

目前我尚未尝试过的一件事情(并且似乎是到目前为止最大的障碍)是Emacs内置的shell(称为"eshell"的shell和/或eshell),因为我已经完美地设置了zsh。不确定是否有一种方法可以在必要时镜像/最小化转换/适应步骤。

我的问题:

  1. eshell是否可以被视为zsh的超集(即,eshell可以做所有zsh能做的事情,而且还可以做更多)?我认为eshell与标准shell(bash、zsh、ksh、tcsh等)相比缺少了很多功能,否则它将成为标准shell之一(如果我错误,请纠正我)。

  2. 使用eshell相比zsh的主要限制是什么?有人从zsh转换到eshell,有没有感觉到zsh有任何关键方面你会非常想念的东西?

  3. 有没有人知道做zsh/eshell功能比较的链接/资源?

  4. 此外,有没有关于从自己通常的shell转换到eshell的任何资源?有关工作流迁移的建议?

  5. 如果eshell不如zsh“强大”,那么eshell相对于zsh的优势是什么?在Emacs中使用eshell的任何技巧和诀窍可以说明学习它所花费的时间吗?

  6. 如果eshell做所有我认为需要的事情,那么是否应该放弃eshell并继续使用zsh?还是少数“高级工作流”值得尝试(我不知道)?

提前感谢。

3个回答

43
关于 M-x eshell
  1. Eshell 不是一个独立的 shell;它是纯 Elisp 实现的,因此不能在 Emacs 之外运行,这也是它不是标准 shell 之一的原因。它没有像 bash/zsh 等那样拥有自己的脚本语言,它使用 Elisp 和一些命令解释功能来使调用 Elisp 更加方便。

  2. 我不能就 zsh vs eshell 发表意见,但我大多数情况下已经从 bash 切换到了 eshell。95% 的时间,eshell 能够完全满足我的需求而无需任何问题。我不把它用于 ssh。另外,一旦启动进程,就不能将其放置到后台(但可以启动时就放在后台)。

  3. 这会非常困难,因为 zsh 有完整的脚本语言,而 eshell 基本上只是 elisp 解释器的接口。你在寻找交互式 shell 中的哪些功能?Eshell 可能可以做到大部分。在命令行上进行条件语句和循环?当然可以。别名、函数、通配符、可编程补全?当然可以。

  4. 我迁移的方法基本上是从头开始。每次我遇到不喜欢的东西或者希望它做到什么时,我都会想办法让它按照我的要求运行。例如,eshell 使用 pcomplete.el 进行可编程补全,因此添加补全函数非常容易。

  5. 与 Emacs 的集成是我最喜欢的优点。你可以将 Elisp 函数传递给 shell 命令。为了一个愚蠢的例子,尝试一下:

  6. message "hello world" | cut -f 1 -d ' '
    一些命令(特别是grep)会出现在emacs缓冲区中,这样您就可以快速跳转到结果。

  7. 这取决于您在emacs中花费的时间多少。如果您在emacs中做所有事情,那么它很有用,因为有时通过eshell将elisp命令与其他命令一起管道连接更容易。如果您不经常在emacs和shell之间复制粘贴,那么这可能不会带来好处,并且您将不得不花费时间将其自定义到您感到舒适的程度。

作为eshell的替代方法,M-x shell在底层运行您的正常shell,解释所有命令(因此无法访问elisp函数),而命令行编辑(因此可编程完成、历史记录等)由emacs完成。我用它进行ssh。

另一种选择是M-x term,它是emacs中的终端仿真器,通常在底部运行一个shell,该shell执行其所有正常操作。然后不需要任何转换/适应步骤。


Eric,由于你是唯一的回复者,因此默认你获得了“最佳答案”。感谢提供信息。 - mt3
我不理解关于“...因为zsh有完整的脚本语言,而eshell基本上是elisp解释器的接口...”这一行。很抱歉,但elisp不是完整的脚本语言? - user1971598
这是一篇非常好的文章。"基本上只有一个Lisp解释器接口"对于你来说应该已经足够了,因为你手头有elisp。 :) - sjas

7

不同的语法

eshell 允许将 elisp 代码与 Shell 命令混合使用,因此它具有一些非常不寻常的语法,您需要小心处理。

需要注意的一件事是命令扩展的语法: zsh 使用的是以下语法:

file $(which foo)

但在 eshell 中,这基本上意味着与

file (which foo)

这意味着在评估elisp表达式(which foo)的结果上运行file命令,通常会导致以下错误:
Symbol's function definition is void: which
。事实证明,在eshell中编写此代码的正确方式是:
file ${which foo}

可移植性

eshell 是使用平台中立的 Emacs Lisp 代码编写的,因此在 Windows 和 *nix 上基本上以相同的方式工作(当然,您可能需要 coreutils 等工具);而在 *nix shell 中让 shell-mode 工作则可能会更加棘手。

我认为我曾经看到过绝对路径补全方面的一些小问题,因为驱动器字母后面有一个冒号,但这并不是什么大问题...


0

我认为你的6个问题可以归结为一个问题:所有在Emacs中能做到的事情,在zsh中都能做到吗?答案是是的,而且还有更多。我不仅指shell、eshell或其他一些Emacs模式,我只是指Emacs

如果我能找到一种方法或模式,至少可以做到与zsh相同的任何事情,那么它就回答了你的问题。这种方法是Emacs中的ansi-term模式,它可以完美地在Emacs中运行zsh,如果你不能在shell或eshell中完成工作,你可以切换到Emacs中的ansi-term模式,这样你的问题就解决了。

eshell只是elisped shell,对于诸如topless等交互/滚动命令并不擅长。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接