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
    • 从其他 Shell 或 DSL 到 Nu
    • 从命令式语言到 Nu
    • 从函数式语言到 Nu
    • Nushell 运算符
  • 设计说明
    • Nushell代码执行原理
  • (不怎么)高级篇
    • 标准库 (预览版)
    • Dataframes
    • 元数据
    • 创建你自己的错误
    • 并行
    • 插件
    • explore

脚本

在 Nushell 中,你可以用 Nushell 语言编写和运行脚本。要运行一个脚本,你可以把它作为一个参数传递给nu命令行程序:

nu myscript.nu

这将在一个新的 Nu 实例中运行脚本直至完成。你也可以使用source在 Nu 的 当前 实例中运行脚本:

source myscript.nu

我们来看一个脚本文件的例子吧:

# myscript.nu
def greet [name] {
  ["hello" $name]
}

greet "world"

脚本文件包含了自定义命令的定义以及主脚本本身,它将在自定义命令定义后运行。

在上面的例子中,首先greet是由 Nushell 解释器定义的,这使得我们之后可以调用这个定义,我们可以把上面的内容写成:

greet "world"

def greet [name] {
  ["hello" $name]
}

Nushell 并不要求定义必须放在脚本中调用该定义之前,你可以把定义放在你觉得舒服的地方。

脚本是如何被处理的

在一个脚本中定义总是先运行,这样我们就可以在脚本中调用定义。

在定义运行之后, 我们从脚本文件的顶部开始, 一个接一个地运行每一组命令。

脚本行

为了更好地理解 Nushell 是如何看待代码行的, 我们来看一个脚本的例子:

a
b; c | d

当这个脚本运行时,Nushell 将首先运行a命令至完成并查看其结果。接下来,Nushell 将按照“分号”部分中的规则运行b; c | d。

参数化脚本

脚本文件可以选择性地包含一个特殊的 "main" 命令。main将在任何其他 Nu 代码之后运行,主要用于向脚本添加位置参数和标志。你可以在脚本名称后面传递参数(nu <script name> <script args>)。比如:

# myscript.nu
def main [x: int] {
  $x + 10
}
nu myscript.nu 100
# => 110

参数类型解释

默认情况下,提供给脚本的参数会被解释为 Type::Any 类型,这意味着它们不受特定数据类型的约束,可以在脚本执行期间动态解释为适合任何可用的数据类型。

在前面的例子中,main [x: int] 表示参数 x 应该具有整数数据类型。但是,如果参数没有显式类型,它们将根据其表观数据类型进行解析。

例如:

# implicit_type.nu
def main [x] {
  $"Hello ($x | describe) ($x)"
}

# explicit_type.nu
def main [x: string] {
  $"Hello ($x | describe) ($x)"
}
nu implicit_type.nu +1
# => Hello int 1

nu explicit_type.nu +1
# => Hello string +1

子命令

一个脚本可以有多个子命令,例如 run 或 build:

# myscript.nu
def "main run" [] {
    print "running"
}

def "main build" [] {
    print "building"
}

def main [] {
    print "hello from myscript!"
}

然后你可以在调用脚本时执行其子命令:

nu myscript.nu
# => hello from myscript!
nu myscript.nu build
# => building
nu myscript.nu run
# => running

与模块不同,main 不需要被导出即可见。在上面的例子中,我们的 main 命令不是 export def,但它在运行 nu myscript.nu 时仍然被执行。如果我们通过运行 use myscript.nu 来使用 myscript 作为一个模块,而不是作为脚本运行 myscript.nu,那么尝试执行 myscript 命令将不起作用,因为 myscript 没有被导出。

需要注意的是,你必须定义一个 main 命令,以便 main 的子命令能够被正确暴露。例如,如果我们只定义了 run 和 build 子命令,它们在运行脚本时将无法访问:

# myscript.nu
def "main run" [] {
    print "running"
}

def "main build" [] {
    print "building"
}
nu myscript.nu build
nu myscript.nu run

这是当前脚本处理方式的一个限制。如果你的脚本只有子命令,你可以添加一个空的 main 来暴露子命令,像这样:

def main [] {}

Shebangs (#!)

在 Linux 和 macOS 上,你可以选择使用 shebang来告诉操作系统一个文件应该被 Nu 解释。例如,在一个名为 myscript 的文件中包含以下内容:

#!/usr/bin/env nu
"Hello World!"
./myscript
# => Hello World!

为了让脚本能够访问标准输入,应该使用 --stdin 标志来调用 nu:

#!/usr/bin/env -S nu --stdin
def main [] {
  echo $"stdin: ($in)"
}
echo "Hello World!" | ./myscript
# => stdin: Hello World!
在GitHub上编辑此页面
Contributors: Justin Ma, Hofer-Julian, 0x4D5352, Jan Klass, voyage200🍬
Prev
控制流
Next
模块