如何在 Emacs 中运行 WSL2?M-x shell RET wsl RET
没有输出任何内容。
这发生在我的 Windows 11 机器上。
在 macOS 上尝试过,Emacs 告诉我的 macOS 机器它的终端对于 WSL 来说太笨了。
当我在搜索引擎上查询它时,我得到的结果是人们想在 WSL 中使用 Emacs,但我想在 Emacs 中运行 WSL。
我认为我需要一个缓冲区,它是一个 PowerShell 终端。
编辑:
尝试使用term
但是当我尝试设置powershell.exe
一些子进程时是一个无效的参数。
Spawning child process: Invalid argument
编辑:
尝试过
(defun powershell (&optional buffer)
"Launches a powershell in buffer *powershell* and switches to it."
(interactive)
(let ((buffer (or buffer "*powershell*"))
(powershell-prog "c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"))
(make-comint-in-buffer "shell" "*powershell*" powershell-prog)
(switch-to-buffer buffer)))
这样M-x powershell
会提供一个 PowerShell 缓冲区,但它不会显示当前目录之类的内容,因此 stdout 似乎已关闭。
与 相同M-x eshell RET powershell RET wsl
。
pwd
它可以工作,但是与 PowerShell 终端相比,缺少了一些东西。
我尝试使用 PowerShell,因为如果在 Emacs 中拥有一个功能齐全的 PowerShell,那么 WSL 也可以像在 PowerShell 终端中一样工作。
答案1
目前我能想到有几种可能性。
简短摘要:
- 使用单行 WSL 命令
- 使用 Emacs 标准输入/
shell
输出eshell
- (未经测试)使用
fakecygpty
(从Emacs Wiki 的 Windows 集成页面) 使用term
。 - 或者简单地在 WSL 下运行 Emacs 的 Linux GUI 版本。
解释:
shell
或的主要问题eshell
是没有真正的终端与之关联的。即使在运行powershell.exe
或cmd.exe
进入它们之后,您仍然可以看到限制:
您可以在 PowerShell 或 CMD 提示符上退格,因为 Emacs 没有字符位置的概念。
您无法
doskey
使用以下方式访问 的命令历史记录F7运行
wsl tput lines
并wsl tput cols
始终返回 24x80,无论屏幕尺寸如何,因为没有适当的 termcap 进行查询(它只是 Emacs 的标准输入/输出)。dir | more
在 CMD 中不起作用。wsl -e stty -a
结果是:stty: 'standard input': Inappropriate ioctl for device
wsl -e vi
结果是:Vim: Warning: Output is not to a terminal Vim: Warning: Input is not from a terminal
所有这些都应该在适当的终端上正常工作。
请注意,您仍然可以在 Emacs shell 中使用 WSL 运行单个 Linux 命令,如您在上面的示例中所见,使用wsl -e <command>
,只要该命令在简单的 stdin/stdout 上运行。
您甚至可以通过以下方式运行多个命令:
M-x term RET wsl -e bash -c "cd ~; ls -lah; cat /etc/os-release" RET
笔记: 对于某些 WSL 命令,您可能会遇到 WSL 输出混乱的错误。Windows 终端(conhost
和 Windows Terminal)在大多数情况下都可以处理此问题,但如果您收到乱码输出wsl -l -v
,则:
首先,请确保你正在通过 运行最新版本的 WSL
wsl --version
。当前版本为 1.0.0。如果没有,则wsl --update
应该会带你到那里,假设你使用的是 Windows 11 22H2。M-x shell
跑步
powershell
:$env:WSL_UTF8=1
wsl -l -v
应该可以正确显示。
尝试使用
term
这个想法不错,但问题是 Windows 版 Emacs 没有附带终端。在 Linux 下,这才是正确答案(见下文)。
可能的解决方案(扩展):
我个人的建议是下面的选项 (4),而 (1) 是我的第二选择...
使用单行 WSL 命令
如上所述,您可以使用以下命令来运行单个或多个命令:
M-x term RET wsl -e bash -c "cd ~; ls -lah; cat /etc/os-release" RET
使用 Emacs 标准输入/
shell
输出eshell
WSL 将工作,只是在 中表现非常非常差
shell
。您应该能够使用以下命令运行交互式 (stdin/stdout) 会话:wsl -e bash --noprofile --norc -li
将有无提示(至少,我还没有解决这个问题)。但是如果你运行该
ls
命令,它实际上应该会返回一个结果。在exit
WSL shell 之前,你可以使用 Linux/WSL 命令。(未经测试)使用
fakecygpty
(从Emacs Wiki 的 Windows 集成页面使用term
。fakecygpty
据悉,Emacs 内部提供了一个 Cygwin 终端,理论上这个终端就可以正常运行 WSL。或者简单地在 WSL 下运行 Emacs 的 Linux GUI 版本。
由于您运行的是 Windows 11,因此 Emacs 可以作为 GUI 应用程序运行,并且外观与 Windows 版本非常相似。您很可能可以调整工作流程以使用视窗来自内部的命令Linux版本的 Emacs,而不是相反。
在 WSL 中使用 Linux 版本的 Emacs 时,你可以使用
term
或ansi-term
来:- 在 Emacs 中运行常规 WSL shell
- 在 Emacs 中运行 PowerShell
- 在 Emacs 中运行 CMD
- 甚至在 Emacs 内部运行
vi
(因为我们都知道 Emacs 是一个很棒的操作系统,只是需要一个很棒的编辑器);-)。 - 您甚至可以运行在单独窗口中显示其自己的 GUI 的 Windows 应用程序。例如,
Show-Command
从 PowerShell 将打开其自己的窗口。或者code .
,等等。
答案2
为了回答问题的第一部分(“如何在 Emacs 中运行 WSL2?”),在 Windows 10 上,我使用了这个,它可以与 WSL1 一起使用,并且仍然可以与 WSL2 一起使用**:
在您的 .emacs 文件中添加:
(defun my-bash-on-windows-shell ()
(interactive)
(let ((explicit-shell-file-name "C:/Windows/System32/bash.exe"))
(shell)))
(global-set-key [f9] 'my-bash-on-windows-shell)
** 需要注意的是,从 WSL 升级到 WSL2 以及从 Ubuntu 18.04 升级到 Ubuntu 22.04 后,提示符 $PS1 不再显示,即使是一个非常简单的提示符:
pwd
/mnt/c/temp
echo $PS1
foo
export PS1=bar
echo $PS1
bar
pwd
/mnt/c/temp
不幸的是,我不知道升级过程的哪一部分删除了$PS1 的显示。
如果我单独运行“C:/Windows/System32/bash.exe”,$PS1 将正常显示。