如何在 Windows Emacs 中运行 WSL2?Mx shell RET wsl RET 不输出任何内容

如何在 Windows Emacs 中运行 WSL2?Mx shell RET wsl RET 不输出任何内容

如何在 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

目前我能想到有几种可能性。

简短摘要:


解释:

shell或的主要问题eshell是没有真正的终端与之关联的。即使在运行powershell.execmd.exe进入它们之后,您仍然可以看到限制:

  • 您可以在 PowerShell 或 CMD 提示符上退格,因为 Emacs 没有字符位置的概念。

  • 您无法doskey使用以下方式访问 的命令历史记录F7

  • 运行wsl tput lineswsl 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) 是我的第二选择...

  1. 使用单行 WSL 命令

    如上所述,您可以使用以下命令来运行单个或多个命令:

    M-x term RET wsl -e bash -c "cd ~; ls -lah; cat /etc/os-release" RET
    
  2. 使用 Emacs 标准输入/shell输出eshell

    WSL 将工作,只是在 中表现非常非常差shell。您应该能够使用以下命令运行交互式 (stdin/stdout) 会话:

    wsl -e bash --noprofile --norc -li
    

    将有无提示(至少,我还没有解决这个问题)。但是如果你运行该ls命令,它实际上应该会返回一个结果。在exitWSL shell 之前,你可以使用 Linux/WSL 命令。

  3. (未经测试)使用fakecygpty(从Emacs Wiki 的 Windows 集成页面使用term

    fakecygpty据悉,Emacs 内部提供了一个 Cygwin 终端,理论上这个终端就可以正常运行 WSL。

  4. 或者简单地在 WSL 下运行 Emacs 的 Linux GUI 版本。

    由于您运行的是 Windows 11,因此 Emacs 可以作为 GUI 应用程序运行,并且外观与 Windows 版本非常相似。您很可能可以调整工作流程以使用视窗来自内部的命令Linux版本的 Emacs,而不是相反。

    在 WSL 中使用 Linux 版本的 Emacs 时,你可以使用termansi-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 将正常显示。

相关内容