跳转至

Nushell 结构化 Shell

一句话说明: Nushell 是一种现代 Shell,将管道中的数据视为结构化表格(而非纯文本),原生支持 JSON/CSV/YAML 解析,让数据处理像查询数据库一样简单。


为什么要学

  1. 结构化管道 — 管道中传递的是表格/记录,不是字符串,告别 awk/sed/cut 的文本拼接
  2. 内置数据格式支持 — 原生解析 JSON、CSV、TOML、YAML、XML,无需 jq 等外部工具
  3. 类型安全 — 有类型系统,命令参数有类型检查,减少运行时错误
  4. 跨平台一致 — Windows/macOS/Linux 行为一致,不再区分 bash/zsh/powershell
  5. 友好的错误信息 — 彩色高亮、精确定位的错误提示

核心概念详解

传统 Shell vs Nushell

操作BashNushell
列出文件ls -la \| awk '{print $5,$9}'ls \| select size name
筛选文件ls \| grep .pyls \| where name =~ ".py"
排序ls -la \| sort -k5 -nls \| sort-by size
JSON 处理cat data.json \| jq '.items[].name'open data.json \| get items.name
进程查看ps aux \| grep python \| awk '{print $2}'ps \| where name == "python" \| get pid

数据类型

类型说明示例
table表格(行列结构)ls 的输出
record记录(键值对){name: "hello", size: 42}
list列表[1, 2, 3]
string字符串"hello"
int / float数字42, 3.14
bool布尔true, false
duration时间长度5min, 2hr
filesize文件大小1gb, 500kb
date日期时间2024-01-01

管道模型

命令1 | 命令2 | 命令3
 表格 → 过滤 → 格式化

每个阶段传递的是结构化数据,不是文本行。

安装与配置

安装

# macOS
brew install nushell

# Linux (cargo)
cargo install nu

# Windows (winget)
winget install nushell

# Windows (scoop)
scoop install nu

设为默认 Shell

# 查找 nu 路径
which nu

# 添加到 /etc/shells(Linux/macOS)
echo $(which nu) | sudo tee -a /etc/shells

# 设为默认
chsh -s $(which nu)

配置文件

# 打开配置
nu> config nu   # 编辑 config.nu
nu> config env  # 编辑 env.nu

# 配置路径
# Linux: ~/.config/nushell/config.nu
# macOS: ~/Library/Application Support/nushell/config.nu
# Windows: %APPDATA%\nushell\config.nu

验证

nu --version
# 0.100.0

快速上手

文件操作

# 列出文件(表格输出)
ls

# 筛选大文件
ls | where size > 1mb

# 按大小排序
ls | sort-by size --reverse | first 10

# 递归查找 Python 文件
glob **/*.py | each { |f| ls $f } | flatten

数据处理

# 打开 JSON 文件
open data.json

# 查询嵌套字段
open config.json | get database.host

# 打开 CSV 并过滤
open sales.csv | where amount > 1000 | sort-by date

# 转换格式
open data.json | to csv | save data.csv

系统信息

# 进程管理
ps | where cpu > 10 | sort-by cpu --reverse

# 系统信息
sys host

# 磁盘使用
sys disks

字符串操作

# 分割
"hello-world-test" | split row "-"

# 替换
"Hello World" | str replace "World" "Nushell"

# 正则匹配
ls | where name =~ '\.py$'

进阶用法

1. 自定义命令

# 定义命令(放入 config.nu)
def greet [name: string, --loud(-l)] {
    let msg = $"Hello, ($name)!"
    if $loud {
        $msg | str upcase
    } else {
        $msg
    }
}

# 使用
greet "World" --loud
# HELLO, WORLD!

2. HTTP 请求与 API 调用

# GET 请求(自动解析 JSON)
http get https://api.github.com/repos/nushell/nushell
| select stargazers_count forks_count open_issues_count

# POST 请求
http post https://httpbin.org/post {name: "test", value: 42}

3. 数据库式查询

# 分组统计
ls | group-by type | transpose key value | each { |row|
    {type: $row.key, count: ($row.value | length)}
}

# 多文件聚合分析
glob *.csv | each { |f| open $f } | flatten
| where status == "error"
| group-by service
| transpose service errors
| insert count { |row| $row.errors | length }
| sort-by count --reverse

4. 管道与闭包

# each - 对每个元素操作
[1 2 3 4 5] | each { |x| $x * $x }
# [1, 4, 9, 16, 25]

# reduce - 累积
[1 2 3 4 5] | reduce { |it, acc| $acc + $it }
# 15

# par-each - 并行处理
glob *.png | par-each { |f| ^convert $f -resize 50% $"thumb_($f)" }

5. 环境变量与路径

# env.nu 中设置
$env.PATH = ($env.PATH | prepend "/usr/local/bin")
$env.EDITOR = "nvim"

# 临时修改
with-env {RUST_LOG: "debug"} { cargo run }

6. 错误处理

# try-catch
try {
    open nonexistent.json
} catch {
    print "文件不存在,使用默认配置"
    {port: 8080, host: "localhost"}
}

7. 外部命令集成

# 调用外部命令(前缀 ^)
^git status

# 外部命令输出转为结构化数据
^docker ps --format "{{json .}}" | lines | each { |l| $l | from json }

# 混合管道
^kubectl get pods -o json | from json | get items | select metadata.name status.phase

常见问题与排错

Q: 某些 bash 语法不工作

Nushell 不是 POSIX Shell,以下语法不同: - 变量:$name(不是 $name${name}) - 字符串拼接:$"hello ($name)" - 管道:结构化数据,不是文本 - 条件:if $x > 0 { ... } 不是 [ $x -gt 0 ]

Q: 如何运行 bash 脚本

^bash script.sh
# 或
^bash -c "echo $HOME && ls"

Q: PATH 配置不生效

env.nu(不是 config.nu)中配置 PATH:

# env.nu
$env.PATH = ($env.PATH | prepend "/home/user/.local/bin")

Q: 命令输出是纯文本而非表格

外部命令默认返回字符串,需要手动解析:

^some-command | lines | split column " " col1 col2 col3

Q: 如何安装插件

# 查看可用插件
plugin list

# 注册插件
plugin add ~/.cargo/bin/nu_plugin_formats

参考资源

  • 官方文档:https://www.nushell.sh/book/
  • GitHub 仓库:https://github.com/nushell/nushell
  • 命令参考:https://www.nushell.sh/commands/
  • Cookbook:https://www.nushell.sh/cookbook/
  • 从 Bash 迁移:https://www.nushell.sh/book/coming_from_bash.html
  • Discord 社区:https://discord.gg/NtAbbGn