eshell 并不是一个真正的 shell,它只能在 emacs 上运行。尽管和 bash、zsh 相比,它的功能很有限,但对大多数人来说已经足够了。此外,由于 eshell 是 由 elisp 编写的,所以它还有其他 shell 所没有的一些特点,比如更强的扩展性和可以使用 emacs 函数。
1. alias
eshell 添加 alias 的方法和 bash 几乎是相同的,并且默认保存在 ~/.eshell/alias。不同的是,eshell 中既可以使用外部命令,也可以使用 emacs 函数,比如:
alias ll ls -al $* alias dl dpkg -l $1 alias e find-file $1 alias v view-file $1 alias sai sudo aptitude install $1
2. histroy
bash 中有很多变量控制命令历史,比如: HISTCONTROL、HISTIGNORE 和 HISTFILESIZE。和它们相对应的 eshell 变量是 eshell-hist-ignoredups、eshell-input-filter(defvar eshell-histignore '("\\`\\(ls\\|ll\\|cd\\|clear\\)\\'" "\\`\\s-*\\'")) (setq eshell-input-filter #'(lambda (str) (let ((regex eshell-histignore)) (not (catch 'break (while regex (if (string-match (pop regex) str) (throw 'break t))))))))
3. completion
zsh 的补全据说非常强大,安装 bash-completion 后 bash 的补全也变得不错。eshell 的补全虽然没有前两者丰富,但却很灵活,自定义也很简单。eshell 的补全依靠 pcomplete,以定义上面的 sai 的补全函数为例。
首先获取当前符合名称的软件包的列表:
(defun pcmpl-package-cache (name) "return a list of packages in cache" (unless (equal name "") (split-string (shell-command-to-string (concat "apt-cache pkgnames " name " 2> /dev/null")))))
(defun pcomplete/sai () "completion for `sai'" (while (pcomplete-here (pcmpl-package-cache (pcomplete-arg 'last)))))
(setq eshell-cmpl-ignore-case t ; 补全时忽略大小写 eshell-cmpl-cycle-completions nil) ; 不要循环补全
在 bash 里我们可以通过 cd - 回到上一个目录,eshell 同样可以。不仅如此,cd -<number>会回到倒数第 number个目录。cd =<REGEXP> 会回到上一个满足 REGEXP 的目录。zsh 中有对路径的别名,cd~X可以进入 ~X 所指代的目录,当目录比较深或很常用时非常方便。这在 eshell 也可以方便地实现。
首先定义一个别名与路径的关联表:
(defvar eshell-path-alist `(("e" . ,user-emacs-directory) ("t" . "/tmp/") ("document" . "~/Documents/") ("download" . "~/Downloads/") ("v" . "~/video/") ("p" . "~/Pictures/")))
(defun eshell/d (arg) (let ((path (cdr (assoc arg eshell-path-alist)))) (eshell/cd path)))
(defun pcomplete/d () (pcomplete-here (mapcar #'car eshell-path-alist)))
来源:这里