はじめに

こんにちは、Nushell プロジェクトへようこそ。このプロジェクトのゴールは、シンプルなコマンドをパイプでつなぎ合わせるというシェルの Unix 哲学を現代の開発スタイルにもちこむことです。

Nu は Bash のような伝統的なシェル、PowerShell などの高度なシェル、関数型プログラミング、システムプログラミングなど、多くの分野からヒントを得ています。しかし Nu は何でもこなせることを目指すのではなく、いくつかのことをうまくこなせることに注力しています。

  • モダンな雰囲気をもつ柔軟なクロスプラットフォームシェルを作ること
  • データ構造を理解するコマンドラインアプリケーションを組みあわせることができること
  • 現代的な CLI アプリケーションが提供する UX をそなえること

Nu になにができるかをみるには、実際に使ってみることが一番です。

lsコマンドを実行して最初に気づくことは、テキストブロックではなく、構造化されたテーブルデータが返ってくることです。

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

このテーブルはディレクトリの内容を別の方法で表示しているだけではありません。このテーブルを利用するとスプレッドシートと同じように、よりインタラクティブにデータを操作できます。

最初に行うことはテーブルをサイズでソートすることです。これを行うにはlsの出力を取得して、カラムの内容に基づいてテーブルをソートするコマンドに入力します。

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

この作業をおこなうために、lsにコマンドライン引数を渡していないことがわかります。代わりに、Nu が提供するsort-byコマンドを利用して、lsコマンドの出力をソートしています。また、一番大きなファイルを表示するために逆順に並び替えています。

Nu にはテーブルを扱うための多くのコマンドが用意されています。例えば、1 キロバイトを超えるファイルのみを表示するようにlsコマンドの出力をフィルターできます。

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

Unix 哲学にあるように、コマンドをつなぎ合わせることで様々な組み合わせを作り出すことができます。別のコマンドをみてみましょう。

> ps
╭─────┬───────┬───────┬──────────────────────────────────────────────┬─────────┬───────┬──────────┬──────────╮
   # │  pid  │ ppid  │                     name                     │ status  │  cpu  │   mem    │ virtual  │
├─────┼───────┼───────┼──────────────────────────────────────────────┼─────────┼───────┼──────────┼──────────┤
   0  87194      1  mdworker_shared                               Sleep     0.00   25.9 MB  418.0 GB 
   1  87183   2314  Arc Helper (Renderer)                        │ Sleep   │  0.00 │  59.9 MB │   1.6 TB │
   2  87182   2314  Arc Helper (Renderer)                        │ Sleep   │  0.23 │ 224.3 MB │   1.6 TB │
   3  87156  87105  Code Helper (Plugin)                         │ Sleep   │  0.00 │  56.0 MB │ 457.4 GB │
...

もしあなたが Linux を利用しているならpsコマンドには馴染みがあるでしょう。これを使うと、現在システムが実行しているすべてのプロセスの状態や名前の一覧を取得することができます。プロセスの CPU 負荷も確認することができます。

CPU をアクティブに利用しているプロセスを表示したい場合はどうでしょうか。さきほどのlsコマンドと同じように、psコマンドが返すテーブルを利用することができます。

> ps | where cpu > 5
╭───┬───────┬───────┬─────────────────────────────────────────┬─────────┬───────┬──────────┬──────────╮
 # │  pid  │ ppid  │                  name                   │ status  │  cpu  │   mem    │ virtual  │
├───┼───────┼───────┼─────────────────────────────────────────┼─────────┼───────┼──────────┼──────────┤
 0  86759  86275  nu                                       Running   6.27   38.7 MB  419.7 GB 
 1  89134      1  com.apple.Virtualization.VirtualMachine  Running  23.92    1.5 GB  427.3 GB 
 2  70414      1  VTDecoderXPCService                      Sleep    19.04   17.5 MB  419.7 GB 
 3   2334      1  TrackpadExtension                        Sleep     7.47   25.3 MB  418.8 GB 
 4   1205      1  iTerm2                                   Sleep    11.92  657.2 MB  421.7 GB 
╰───┴───────┴───────┴─────────────────────────────────────────┴─────────┴───────┴──────────┴──────────╯

これまで、lspsを利用してファイルやプロセスの一覧を表示しました。Nu はこの他にも便利なテーブルを作り出すコマンドを提供します。次にdatesysをみてみましょう。

date nowを実行すると、現在の日時と時間に関する情報が得られます。

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

sysは Nu が実行されているシステムに関する情報を提供します。

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

これはさきほどまでのテーブルと少し異なります。sysコマンドは単純な値ではなくセルに構造化されたテーブルを含むテーブルを提供します。このデータを見るには表示する列を選択する必要があります。

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

getコマンドを利用するとテーブルのカラムの内容を調べることができます。ここでは、Nu が実行されているホストに関する情報を含む"host"列を調べています。OS の名前、ホスト名、CPU などです。システム上のユーザーの名前を取得してみましょう。

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

現在、システムには"jonathan"という名前のユーザが1人だけいます。列の名前だけではなくパスも渡せることに気づくでしょう。Nu はパスを受け取るとテーブルの対応するデータを取得します。

テーブルデータではなく、文字列"jonathan"を取得したことに気づかれたかもしれません。Nu はテーブルだけでなく文字列も扱います。文字列は Nu 以外のコマンドを扱う上で重要な役割をはたします。

実際に Nu の外で文字列がどのように機能するか見てみましょう。先ほどの例で外部のechoコマンドを実行します。(^は組込みのechoコマンドを使用しないよう指示しています)。

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

するどい読者にはこれが以前ものと似ていると思われるでしょう。しかし、さきほどの出力でechoを呼び出しているという重要な違いがあります。このように、Nu からデータをecho(またはgitのような Nu 以外の任意のコマンド)にわたすことができるのです。

注:Nu の組み込みコマンドのヘルプテキストは、helpコマンドで検出できます。

> help path
Explore and manipulate paths.

There are three ways to represent a path:

* As a path literal, e.g., '/home/viking/spam.txt'
* As a structured path: a table with 'parent', 'stem', and 'extension' (and
* 'prefix' on Windows) columns. This format is produced by the 'path parse'
  subcommand.
* As an inner list of path parts, e.g., '[[ / home viking spam.txt ]]'.
  Splitting into parts is done by the `path split` command.

All subcommands accept all three variants as an input. Furthermore, the 'path
join' subcommand can be used to join the structured path or path parts back into
the path literal.

Usage:
  > path

Subcommands:
  path basename - Get the final component of a path
  path dirname - Get the parent directory of a path
  path exists - Check whether a path exists
  path expand - Try to expand a path to its absolute form
  path join - Join a structured path or a list of path parts.
  path parse - Convert a path into structured data.
  path relative-to - Get a path as relative to another path.
  path split - Split a path into parts by a separator.
  path type - Get the type of the object a path refers to (e.g., file, dir, symlink)

Flags:
  -h, --help
      Display this help message