Windows 下 Emacs 中的 zsh shell
zsh shell
![](/data/attachment/album/201903/12/104236yuzuuurhp8zr1h13.jpg)


运行跨平台 shell（例如 Bash 或 zsh）的最大优势在于你能在多平台上使用同样的语法和脚本。在 Windows 上设置（替换）shell 挺麻烦的，但所获得的回报远远超出这小小的付出。


![zsh shell inside Emacs on Windows](/data/attachment/album/201903/12/104246ofgp099aw0f06z1p.png)


MSYS2 子系统允许你在 Windows 上运行 Bash 或 zsh 之类的 shell。使用 MSYS2 很重要的一点在于确保搜索路径都指向 MSYS2 子系统本身：存在太多依赖关系了。


MSYS2 安装后默认的 shell 就是 Bash；zsh 则可以通过包管理器进行安装：



```
pacman -Sy zsh
```

通过修改 `/etc/passwd` 文件可以设置 zsh 作为默认 shell，例如：



```
mkpasswd -c | sed -e 's/bash/zsh/' | tee -a /etc/passwd
```

这会将默认 shell 从 bash 改成 zsh。


要在 Windows 上的 Emacs 中运行 zsh ，需要修改 `shell-file-name` 变量，将它指向 MSYS2 子系统中的 zsh 二进制文件。该二进制 shell 文件在 Emacs `exec-path` 变量中的某个地方。



```
(setq shell-file-name (executable-find "zsh.exe"))
```

不要忘了修改 Emacs 的 `PATH` 环境变量，因为 MSYS2 路径应该先于 Windows 路径。接上一个例子，假设 MSYS2 安装在 `c:\programs\msys2` 中，那么执行：



```
(setenv "PATH" "C:\\programs\\msys2\\mingw64\\bin;C:\\programs\\msys2\\usr\\local\\bin;C:\\programs\\msys2\\usr\\bin;C:\\Windows\\System32;C:\\Windows")
```

在 Emacs 配置文件中设置好这两个变量后，在 Emacs 中运行：



```
M-x shell
```

应该就能看到熟悉的 zsh 提示符了。


Emacs 的终端设置（eterm）与 MSYS2 的标准终端设置（xterm-256color）不一样。这意味着某些插件和主题（提示符）可能不能正常工作 - 尤其在使用 oh-my-zsh 时。


检测 zsh 否则在 Emacs 中运行很简单，使用变量 `$INSIDE_EMACS`。


下面这段代码片段取自 `.zshrc`（当以交互式 shell 模式启动时会被加载），它会在 zsh 在 Emacs 中运行时启动 git 插件并更改主题：



```
# Disable some plugins while running in Emacs
if [[ -n "$INSIDE_EMACS" ]]; then
  plugins=(git)
  ZSH_THEME="simple"
else
  ZSH_THEME="compact-grey"
fi
```

通过在本地 `~/.ssh/config` 文件中将 `INSIDE_EMACS` 变量设置为 `SendEnv` 变量……



```
Host myhost
SendEnv INSIDE_EMACS
```

……同时在 ssh 服务器的 `/etc/ssh/sshd_config` 中设置为 `AcceptEnv` 变量……



```
AcceptEnv LANG LC_* INSIDE_EMACS
```

……这使得在 Emacs shell 会话中通过 ssh 登录另一个运行着 zsh 的 ssh 服务器也能工作的很好。当在 Windows 下的 Emacs 中的 zsh 上通过 ssh 远程登录时，记得使用参数 `-t`，`-t` 参数会强制分配伪终端（之所以需要这样，时因为 Windows 下的 Emacs 并没有真正的 tty）。


跨平台，开源真是个好东西……




---


via: <https://www.onwebsecurity.com/configuration/zsh-shell-inside-emacs-on-windows.html>


作者：[Peter Mosmans](https://www.onwebsecurity.com/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
![zsh shell inside Emacs on Windows](/images/zsh-shell-inside-emacs-on-windows.png)

The most obvious advantage of running a cross-platform shell (for example Bash or zsh) is that you can use the same syntax and scripts on multiple platforms. Setting up (alternative) shells on Windows can be pretty tricky, but the small investment is well worth the reward.

The MSYS2 subsystem allows you to run shells like Bash or zsh on Windows. An important part of MSYS2 is making sure that the search paths are all pointing to the MSYS2 subsystem: There are a lot of dependencies.

Bash is the default shell once MSYS2 is installed; zsh can be installed using the package manager:

```
pacman -Sy zsh
```

Setting zsh as default shell can be done by modifying the ```
/etc/passwd
```

file, for instance:

```
mkpasswd -c | sed -e 's/bash/zsh/' | tee -a /etc/passwd
```

This will change the default shell from bash to zsh.

Running zsh under Emacs on Windows can be done by modifying the
```
shell-file-name
```

variable, and pointing it to the zsh binary from the MSYS2
subsystem. The shell binary has to be somewhere in the Emacs ```
exec-path
```

variable.

```
(setq shell-file-name (executable-find "zsh.exe"))
```

Don't forget to modify the PATH environment variable for Emacs, as the MSYS2 paths should be resolved before Windows paths. Using the same example, where MSYS2 is installed under

c:\programs\msys2:

```
(setenv "PATH" "C:\\programs\\msys2\\mingw64\\bin;C:\\programs\\msys2\\usr\\local\\bin;C:\\programs\\msys2\\usr\\bin;C:\\Windows\\System32;C:\\Windows")
```

After setting these two variables in the Emacs configuration file, running

M-x shellin Emacs should bring up the familiar zsh prompt.

Emacs' terminal settings (eterm) are different than MSYS2' standard terminal settings (xterm-256color). This means that some plugins or themes (prompts) might not work - especially when using oh-my-zsh.

Detecting whether zsh is started under Emacs is easy, using the variable

$INSIDE_EMACS. This codesnippet in

.zshrc(which will be sourced for interactive shells) only enables the git plugin when being run in Emacs, and changes the theme

```
# Disable some plugins while running in Emacs
if [[ -n "$INSIDE_EMACS" ]]; then
plugins=(git)
ZSH_THEME="simple"
else
ZSH_THEME="compact-grey"
fi
```

By adding the ```
INSIDE_EMACS
```

variable to the local ```
~/.ssh/config
```

as ```
SendEnv
```

variable...

```
Host myhost
SendEnv INSIDE_EMACS
```

... and to a ssh server as ```
AcceptEnv
```

variable in ```
/etc/ssh/sshd_config
```

...

```
AcceptEnv LANG LC_* INSIDE_EMACS
```

... this even works when ssh'ing inside an Emacs shell session to another ssh
server, running zsh. When ssh'ing in the zsh shell inside Emacs on Windows,
using the parameters ```
-t -t
```

forces pseudo-tty allocation (which is
necessary, as Emacs on Windows don't have a true tty).

Cross-platform, open-source goodyness...

## Comments

comments powered by Disqus