Nushell
安装 Nu !
快速开始
  • Nushell 之书
  • 命令参考列表
  • 实战指南
  • 语言参考指南
  • 贡献指南
博客
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
安装 Nu !
快速开始
  • Nushell 之书
  • 命令参考列表
  • 实战指南
  • 语言参考指南
  • 贡献指南
博客
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
  • 简介
  • 安装
    • 默认 Shell
  • 快速入门
    • 快速入门
    • 在系统中四处移动
    • 用 Nu 的方式思考
    • Nushell 速查表
  • Nu 基础篇
    • 数据类型
    • 加载数据
    • 管道
    • 处理字符串
    • 处理列表
    • 处理记录(Records)
    • 处理表格
    • 导航和访问结构化数据
    • 特殊变量
  • Nushell 编程
    • 自定义命令
    • 别名
    • 运算符
    • 变量
    • 控制流
    • 脚本
    • 模块
      • 使用模块
      • 创建模块
    • 覆层
    • 排序
    • 测试你的 Nushell 代码
    • 脚本调试
    • 最佳实践
  • Nu 作为 Shell 使用
    • 配置
    • 环境
    • 标准输入、输出和退出码
    • 运行系统(外部)命令
    • 如何配置第三方提示
    • 目录栈
    • Reedline,Nu 的行编辑器
    • 自定义补全
    • 外部命令
    • Nu 的配色和主题
    • 钩子
    • 后台任务
  • 迁移到 Nu
    • 从 Bash 到 Nu
    • 从 CMD.EXE 到 Nu
    • 从 PowerShell 到 Nu
    • 从其他 Shell 或 DSL 到 Nu
    • 从命令式语言到 Nu
    • 从函数式语言到 Nu
    • Nushell 运算符
  • 设计说明
    • Nushell代码执行原理
  • (不怎么)高级篇
    • 标准库 (预览版)
    • Dataframes
    • 元数据
    • 创建你自己的错误
    • 并行
    • 插件
    • explore
    • 使用 tui 构建终端用户界面
    • MCP 服务器

脚本调试

Nushell 内置了脚本调试器。运行 nu --dap 会启动一个 Debug Adapter Protocol(DAP)服务器,VS Code、Neovim 和 Zed 等编辑器正是通过该协议来驱动调试器的。当你的编辑器配置好使用该调试器后,你可以在 .nu 文件中设置断点、逐行单步执行脚本并深入管道阶段、查看变量和 $env、在脚本暂停时评估表达式,甚至可以沿已执行路径向后单步回溯。

配置你的编辑器

编辑器会自行启动 nu --dap 并通过进程的标准输入和输出流与其通信,因此它只需知道要运行的命令(nu,附带参数 --dap)以及要启动哪个脚本。调试器是默认构建的一部分(即 dap Cargo 特性)。

例如,在 Neovim 中配合 nvim-dap 使用:

local dap = require('dap')

dap.adapters.nu = {
  type = 'executable',
  command = 'nu',
  args = { '--dap' },
}

dap.configurations.nu = {
  {
    type = 'nu',
    request = 'launch',
    name = 'Debug this script',
    program = '${file}',
  },
}

VS Code 则需要一个为 Nushell 注册调试器的扩展,随后从 launch.json 中读取相同的启动设置。

调试器在运行脚本前会加载你的 env.nu 和 config.nu,因此脚本能看到与你的 shell 相同的自定义命令、别名和环境。在参数中添加 -n(args = { '--dap', '-n' })可改为从默认配置启动。在解析配置文件期间,$nu.is-dap 的值为 true。

启动配置项

启动配置支持以下设置项:

配置项默认值说明
program待调试的 .nu 脚本的绝对路径。必填。
args[]传递给 main 或 entryPoint 命令的参数字符串列表。其解析方式与 nu <script> ...args 相同。
cwd运行脚本的工作目录。
stopOnEntryfalse是否在第一行代码运行前暂停。
entryPoint在脚本顶层执行完毕后运行的命令,适用于仅定义命令的文件。若未指定且脚本包含 main,则运行 main。
timeTraveltrue记录运行的每一行,以便能够向后单步回溯。若为 false,则仅记录脚本暂停的位置。
timeTravelMaxSteps10000保留的记录步数。较早的记录将被丢弃。

脚本的运行方式与 nu <script> ...args 一致:先执行顶层代码,然后使用 args 中的参数执行 main,或者执行 entryPoint 中指定的命令。

断点与单步执行

在某一行设置断点,脚本就会在该行暂停。如果在无法暂停的行(例如注释行)设置断点,断点会自动移至下一行可暂停的代码处。

一行代码通常包含多个步骤。在 let doubled = ($nums | each {|n| $n * 2 }) 中,let、each 调用以及闭包体各自独立运行。普通断点会在其中的第一步暂停,随后在闭包体针对每个元素执行时再次暂停。而在特定列设置的行内断点(在 VS Code 中为 Shift+F9)则仅会在该特定步骤处暂停。

断点还可以是:

  • 条件断点:条件是一个 Nushell 表达式,例如 $n == 3,脚本仅在表达式为 true 时暂停。
  • 日志断点(Logpoints):断点不会暂停执行,而是向调试控制台输出一条消息。花括号中的表达式会被求值,例如 names has {$names | length} items 会输出 names has 2 items。

**运行时错误(Runtime errors)**异常过滤器默认处于开启状态,当某个命令引发错误时(包括会被 try 块捕获的错误),调试器会暂停脚本。编辑器会显示该错误的代码和消息。

脚本暂停时,你可以继续执行、单步跳过整行、单步进入命令调用或管道阶段,或者单步跳出当前命令。调用栈(Call Stack)会展示通往当前行的命令和闭包调用层级。

检查变量与值

当脚本暂停时,编辑器的变量视图会展示:

  • Locals(局部变量):当前作用域内的变量、$in,以及 return(最后一步的值)。
  • Pipeline(管道值):在两个管道阶段的分界处,流入下一个命令的值。
  • Globals(全局变量):$nu 和 $env,包含脚本对环境所做的任何更改。
  • Registers(寄存器):求值器的内部工作值,用于查看 Nushell 底层执行细节。
  • Process(进程输出):脚本运行的外部命令的最新输出。

嵌套的记录、列表和表格在你展开时会逐级加载,因此在查看内部结构之前,庞大的数据结构不会拖慢任何操作。数据流(Stream)仅作描述而不予读取,因此查看数据流不会消耗其内容。

监视表达式(Watch expressions)、调试控制台以及将鼠标悬停在变量上,都会使用暂停时的值来对 Nushell 表达式求值。它们在脚本状态的副本上运行,因此不会修改脚本的变量。

来自 print 和外部命令的输出会发送到编辑器的调试控制台。脚本没有附加终端,因此外部命令不会接收标准输入。

向后单步回溯

Nushell 无法反向执行代码,因此调试器会在每一行记录当时的状态(当 timeTravel 开启时,默认开启)。**单步后退(Step Back)和反向继续(Reverse Continue)**会沿这些历史记录向后回退,移动到上一行或上一个断点,并展示当时的变量和调用栈。从回退位置向前单步执行会沿着记录向前推进,直至到达最新的执行步骤,随后脚本恢复正常运行。已经执行过的命令不会被撤销:脚本已写入的文件依然保持写入状态。

**重启(Restart)**会在同一个会话中从头再次运行脚本,重新从磁盘读取脚本内容并保留你的断点。

使用限制

  • 调试器目前只能启动新脚本,无法附加到已在运行的 Nushell 进程。
  • 脚本暂停时无法修改变量的值。
  • 暂不支持函数断点和命中计数断点。
  • 变量视图始终显示最内层的命令或闭包。在调用栈中选择调用方会跳转到其所在行,但变量视图仍保持为最内层帧的状态。
  • input 和 input list 需要支持调试器提示对话框的客户端。在其他编辑器中,脚本会在提示处等待,并在 10 分钟后失败。input listen 在调试器中无法正常工作。
在GitHub上编辑此页面
Contributors: Jianjun Wang, passionworkeer
Prev
测试你的 Nushell 代码
Next
最佳实践