介绍

你好,欢迎来到 Nushell 项目。这个项目的目标是继承 Unix Shell 中用管道把简单的命令连接在一起的理念,并将其带到更具现代风格的开发中。

Nu 汲取了很多常见领域的灵感:传统 Shell 比如 Bash、基于对象的 Shell 比如 PowerShell、逐步类型化的语言比如 TypeScript、函数式编程、系统编程,等等。但是,Nu 并不试图成为万金油,而是把精力集中在做好这几件事上:

  • 作为一个具有现代感的灵活的跨平台 Shell;
  • 作为一种现代的编程语言,解决与数据有关的问题;
  • 给予清晰的错误信息和干净的 IDE 支持;

了解 Nu 能做什么的最简单的方法是从一些例子开始,所以让我们深入了解一下。

当你运行ls这样的命令时,你会注意到的第一件事是,你得到的不是一个文本块,而是一个结构化的表格:

  1. > ls
  2. ╭────┬───────────────────────┬──────┬───────────┬─────────────╮
  3. # │ name │ type │ size │ modified │
  4. ├────┼───────────────────────┼──────┼───────────┼─────────────┤
  5. 0 404.html file 429 B 3 days ago
  6. 1 CONTRIBUTING.md file 955 B 8 mins ago
  7. 2 Gemfile file 1.1 KiB 3 days ago
  8. 3 Gemfile.lock file 6.9 KiB 3 days ago
  9. 4 LICENSE file 1.1 KiB 3 days ago
  10. 5 README.md file 213 B 3 days ago
  11. ...

该表不仅仅是以不同的方式显示目录,就像电子表格中的表一样,它还允许我们以更加互动的方式来处理数据。

我们要做的第一件事是按大小对我们的表进行排序。要做到这一点,我们将从ls中获取输出,并将其输入到一个可以根据列的内容对表进行排序的命令中:

  1. > ls | sort-by size | reverse
  2. ╭────┬───────────────────────┬──────┬───────────┬─────────────╮
  3. # │ name │ type │ size │ modified │
  4. ├────┼───────────────────────┼──────┼───────────┼─────────────┤
  5. 0 Gemfile.lock file 6.9 KiB 3 days ago
  6. 1 SUMMARY.md file 3.7 KiB 3 days ago
  7. 2 Gemfile file 1.1 KiB 3 days ago
  8. 3 LICENSE file 1.1 KiB 3 days ago
  9. 4 CONTRIBUTING.md file 955 B 9 mins ago
  10. 5 books.md file 687 B 3 days ago
  11. ...

你可以看到,为了达到这个目的,我们没有向ls传递命令行参数。取而代之的是,我们使用了 Nu 提供的sort-by命令来对ls命令的输出进行排序。为了在顶部看到最大的文件,我们还使用了reverse命令。

Nu 提供了许多可以对表进行操作的命令,例如,我们可以过滤ls表的内容,使其只显示超过 1 千字节的文件。

  1. > ls | where size > 1kb
  2. ╭───┬───────────────────┬──────┬─────────┬────────────╮
  3. # │ name │ type │ size │ modified │
  4. ├───┼───────────────────┼──────┼─────────┼────────────┤
  5. 0 Gemfile file 1.1 KiB 3 days ago
  6. 1 Gemfile.lock file 6.9 KiB 3 days ago
  7. 2 LICENSE file 1.1 KiB 3 days ago
  8. 3 SUMMARY.md file 3.7 KiB 3 days ago
  9. ╰───┴───────────────────┴──────┴─────────┴────────────╯

就像在 Unix 哲学中一样,能够让命令相互对话给我们提供了在许多不同的组合中对命令进行混搭的方法。我们来看看一个不同的命令:

  1. > ps
  2. ╭─────┬──────┬──────────────────────┬─────────┬───────┬───────────┬──────────╮
  3. # │ pid │ name │ status │ cpu │ mem │ virtual │
  4. ├─────┼──────┼──────────────────────┼─────────┼───────┼───────────┼──────────┤
  5. 0 7570 nu Running 1.96 23.2 MiB 32.8 GiB
  6. 1 3533 remindd Sleep 0.00 103.6 MiB 32.3 GiB
  7. 2 3495 TVCacheExtension Sleep 0.00 11.9 MiB 32.2 GiB
  8. 3 3490 MusicCacheExtension Sleep 0.00 12.9 MiB 32.2 GiB
  9. ...

如果你使用过 Linux,你可能对ps命令很熟悉。通过它,我们可以得到一个当前系统正在运行的所有进程的列表,它们的状态是什么,以及它们的名字是什么,我们还可以看到这些进程的 CPU 负载。

如果我们想显示那些正在活跃使用 CPU 的进程呢?就像我们之前对ls命令所做的那样,我们也可以利用ps命令返回给我们的表格来做到:

  1. > ps | where cpu > 5
  2. ╭───┬──────┬────────────────┬─────────┬────────┬───────────┬──────────╮
  3. # │ pid │ name │ status │ cpu │ mem │ virtual │
  4. ├───┼──────┼────────────────┼─────────┼────────┼───────────┼──────────┤
  5. 0 1583 Terminal Running 20.69 127.8 MiB 33.0 GiB
  6. 1 579 photoanalysisd Running 139.50 99.9 MiB 32.3 GiB
  7. ╰───┴──────┴────────────────┴─────────┴────────┴───────────┴──────────╯

到目前为止,我们一直在使用lsps来列出文件和进程。Nu 还提供了其他可以创建有用信息表格的命令。接下来,让我们试一下datesys

运行date now输出关于当前日期和时间的信息:

  1. > date now
  2. 2022-03-07 14:14:51.684619600 -08:00

为了将获得的日期以表格形式展示,我们可以把它输入到 date to-table中:

  1. > date now | date to-table
  2. ╭───┬──────┬───────┬─────┬──────┬────────┬────────┬──────────╮
  3. # │ year │ month │ day │ hour │ minute │ second │ timezone │
  4. ├───┼──────┼───────┼─────┼──────┼────────┼────────┼──────────┤
  5. 0 2022 3 7 14 45 3 -08:00
  6. ╰───┴──────┴───────┴─────┴──────┴────────┴────────┴──────────╯

运行sys可以得到 Nu 所运行的系统的信息:

  1. > sys
  2. ╭───────┬───────────────────╮
  3. host {record 6 fields}
  4. cpu [table 4 rows]
  5. disks [table 3 rows]
  6. mem {record 4 fields}
  7. temp [table 1 row]
  8. net [table 4 rows]
  9. ╰───────┴───────────────────╯

这与我们之前看到的表格有些不同。sys命令输出了一个在单元格中包含结构化表格而非简单值的表格。要查看这些数据,我们需要 get 待查看的列:

  1. > sys | get host
  2. ╭────────────────┬────────────────────────╮
  3. name Debian GNU/Linux
  4. os version 11
  5. kernel version 5.10.92-v8+
  6. hostname lifeless
  7. uptime 19day 21hr 34min 45sec
  8. sessions [table 1 row]
  9. ╰────────────────┴────────────────────────╯

get命令让我们深入表的某一列内容中。在这里,我们要查看的是 “host” 列,它包含了 Nu 正在运行的主机的信息:操作系统名称、主机名、CPU,以及更多。让我们来获取系统上的用户名:

  1. > sys | get host.sessions.name
  2. ╭───┬────╮
  3. 0 jt
  4. ╰───┴────╯

现在,系统中只有一个名为 “jt” 的用户。你会注意到,我们可以传递一个列路径(host.sessions.name部分),而不仅仅是简单的列名称。Nu 会接受列路径并输出表中相应的数据。

你可能已经注意到其他一些不同之处:我们没有一个数据表,而只有一个元素:即字符串 “jt”。Nu 既能处理数据表,也能处理字符串。字符串是使用 Nu 外部命令的一个重要部分。

让我们看看字符串在 Nu 外部命令里面是如何工作的。我们以之前的例子为例,运行外部的echo命令(^告诉 Nu 不要使用内置的echo命令):

  1. > sys | get host.sessions.name | each { |it| ^echo $it }
  2. jt

敏锐的读者可能会发现这看起来和我们之前的非常相似!确实如此,但有一个重要的区别:我们用前面的值调用了^echo。这允许我们把数据从 Nu 中传到外部命令echo(或者 Nu 之外的任何命令,比如git)。

获取帮助

任何 Nu 的内置命令的帮助文本都可以通过help命令来找到。要查看所有命令,请运行help commands。你也可以通过执行help -f <topic>来搜索一个主题:

  1. > help path
  2. Explore and manipulate paths.
  3. There are three ways to represent a path:
  4. * As a path literal, e.g., '/home/viking/spam.txt'
  5. * As a structured path: a table with 'parent', 'stem', and 'extension' (and
  6. * 'prefix' on Windows) columns. This format is produced by the 'path parse'
  7. subcommand.
  8. * As an inner list of path parts, e.g., '[[ / home viking spam.txt ]]'.
  9. Splitting into parts is done by the `path split` command.
  10. All subcommands accept all three variants as an input. Furthermore, the 'path
  11. join' subcommand can be used to join the structured path or path parts back into
  12. the path literal.
  13. Usage:
  14. > path
  15. Subcommands:
  16. path basename - Get the final component of a path
  17. path dirname - Get the parent directory of a path
  18. path exists - Check whether a path exists
  19. path expand - Try to expand a path to its absolute form
  20. path join - Join a structured path or a list of path parts.
  21. path parse - Convert a path into structured data.
  22. path relative-to - Get a path as relative to another path.
  23. path split - Split a path into parts by a separator.
  24. path type - Get the type of the object a path refers to (e.g., file, dir, symlink)
  25. Flags:
  26. -h, --help
  27. Display this help message