PAYATHON 2026

Jupyter Notebook 中 Bash (WSL) 报 Kernel does not exist 如何解决?

排障赵师傅

结论

先修正内核启动方式。当前 kernel.json 启动的是 WSL 中的交互式 Bash,没有调用 bash_kernel,因此无法作为 Jupyter 内核运行。在 Windows 的 Python 环境中安装 bash_kernel,也不会改变这条启动命令的行为。

Kernel does not exist: <kernel-id> 表示服务器找不到该 ID 对应的运行中内核。它可能是内核启动失败后引发的错误,也可能来自已经失效的会话。仅凭这段 traceback,还无法确定最初的失败原因。

建议将 Jupyter Notebook 和 bash_kernel 都放在 WSL 的同一个 Python 环境中运行,减少 Windows 与 WSL 之间的路径、连接和环境差异,也无需手工修改全局环境变量。目前没有足够依据建议降级 Tornado。

当前 kernel.json 为什么不能工作

这份配置实际执行的命令是:

wsl.exe bash -c "exec bash -l -i" -- "{connection_file}"

其中:

  • exec bash -l -i 启动登录式交互 Bash。
  • {connection_file} 作为外层 bash -c 的位置参数传入,但命令没有读取或转交它。
  • 整条命令没有调用 bash_kernel。

Jupyter 内核需要读取连接文件,并通过 Jupyter 消息协议与服务器通信。普通 Bash 没有这部分功能,即使进程仍在运行,也无法完成内核连接。

display_name 只控制菜单中的显示名称,写成 Bash (WSL) 也不会自动建立 Jupyter 与 WSL 内核之间的通信。

先确认实际使用的环境和启动日志

在启动 Notebook 的 Windows Conda 环境中执行:

python -c "import sys; print(sys.executable)"
python -m pip show notebook jupyter_server jupyter_client bash_kernel tornado
python -m pip check
python -m jupyter kernelspec list --json

查看最后一条命令返回的 resource_dir,确认编辑的 kernel.json 确实是当前使用的那份。不同环境或安装位置可能有同名配置。

然后从终端启动 Notebook,并保留调试日志:

python -m notebook --debug

新建一个 Bash Notebook,在日志中查找第一条内核启动错误,尤其要留意 404 之前的异常。缺少模块、找不到可执行文件、无法读取连接文件和内核连接超时,各有不同的处理方式。

如果日志显示内核已正常连接,之后才出现针对旧 ID 的 404,可以尝试关闭旧页面,重新打开 Notebook 并选择内核。单纯刷新页面无法修复当前的启动配置。

推荐做法:在 WSL 内安装并启动整套环境

先在 PowerShell 中查看 WSL 发行版及默认选择:

wsl --list --verbose

进入准备使用的发行版,在 WSL 终端中执行:

python3 -m venv ~/.venvs/jupyter-bash
source ~/.venvs/jupyter-bash/bin/activate

python -m pip install notebook bash_kernel
python -m bash_kernel.install
python -m pip check
python -m jupyter kernelspec list --json

python -m notebook --no-browser

执行这些命令前,WSL 内需要已经安装 Python 3,并支持创建虚拟环境。如果 venv 创建失败,先按发行版的提示安装相应组件,再继续。

这里的 notebook 和 bash_kernel 都要安装在 WSL 的虚拟环境中。Windows Conda 环境中的安装不能替代它们。

在 Windows 浏览器中打开 WSL 终端打印的访问地址,选择新注册的 Bash 内核。菜单名称以安装生成的配置为准,可能显示为 Bash。

虚拟环境激活脚本只影响当前终端及其启动的进程,不需要手工添加系统级 PATH。以后启动时,在 WSL 中重新激活该环境即可。

正常的启动配置应是什么样

优先使用以下命令生成配置:

python -m bash_kernel.install

当 Jupyter 和内核都运行在 WSL 中时,生成的配置应通过 Python 启动 bash_kernel,结构类似:

{
  "argv": [
    "/home/<linux-user>/.venvs/jupyter-bash/bin/python",
    "-m",
    "bash_kernel",
    "-f",
    "{connection_file}"
  ],
  "display_name": "Bash",
  "language": "bash"
}

<linux-user> 需要替换为实际的 Linux 用户名。具体路径以安装命令生成的配置为准,不要直接照搬示例。

-f 将连接文件交给 bash_kernel,由它与 Jupyter 通信,再执行 Bash 代码。language 和 display_name 都不能替代这条启动命令。

新建 Notebook 后,可以执行:

printf 'Bash kernel is running\n'
uname -s

确认命令能返回结果,后续单元格也能继续执行,再检查中断或重启操作是否正常。这些操作都正常,才说明内核已经建立连接。

如果必须保留 Windows 端的 Jupyter

从 Windows Jupyter 启动 WSL 内核还需要额外配置。把 wsl.exe 后面的命令改成 Python 后,至少还要确认:

  • 所选 WSL 发行版中已安装 bash_kernel,且启动命令使用了正确的 Python。
  • Windows 生成的连接文件路径已转换为 WSL 可访问的路径。
  • 连接文件中的地址和端口允许 Windows 服务器与 WSL 内核互通,具体取决于 WSL 网络配置。

例如,Windows 的 C:\Users\... 路径不能直接当作 Linux 文件路径使用。转换路径后,还要确认文件确实可读。如果暂时没有跨系统运行的必要,先让整套环境在 WSL 内运行,会更容易排查问题。

Git Bash 是另一套 Bash 环境。当前配置调用的是 wsl.exe,安装 Git Bash 无法修复这份配置,也不应将 Git Bash 的路径与 WSL 的启动配置混用。

报错中的包名是 tornado。它出现在 traceback 中,是因为 Jupyter 通过它返回 HTTP 错误,仅凭这一点无法判断 Tornado 是否存在版本问题。只有启动日志或依赖检查明确指出兼容性冲突时,才应按相关依赖要求调整版本。

备注:内容仅供参考。