はじめに

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

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

  • 現代のGithub時代のプログラマ向けの柔軟でクロスプラットフォームなシェルを作ること

  • データ構造を理解しながら、コマンドラインアプリケーションを組み合わせて使えるようにすること

  • 現代的なCLIアプリケーションが提供するUXをそなえること

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

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

> ls
----+------------------+-----------+----------+----------+----------------+----------------
# | name | type | readonly | size | accessed | modified
----+------------------+-----------+----------+----------+----------------+----------------
0 | .azure | Directory | | 4.1 KB | 2 months ago | a week ago
1 | IMG_1291.jpg | File | | 115.5 KB | a month ago | 4 months ago
2 | Cargo.toml | File | | 3.1 KB | 17 minutes ago | 17 minutes ago
3 | LICENSE | File | | 1.1 KB | 2 months ago | 2 months ago
4 | readonly.txt | File | readonly | <empty> | a month ago | a month ago
5 | target | Directory | | 4.1 KB | 2 days ago | 15 minutes ago
...

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

最初に行うことはテーブルを名前でソートすることです。これを行うには、lsコマンドの出力を、列の内容に基づいてテーブルをソートできるコマンドに送ります。

> ls | sort-by name
----+------------------+-----------+----------+----------+----------------+----------------
# | name | type | readonly | size | accessed | modified
----+------------------+-----------+----------+----------+----------------+----------------
0 | .azure | Directory | | 4.1 KB | 2 months ago | a week ago
1 | .cargo | Directory | | 4.1 KB | 2 months ago | 2 months ago
2 | .editorconfig | File | | 148 B | 2 months ago | 2 months ago
3 | .git | Directory | | 4.1 KB | 2 months ago | 20 minutes ago
4 | .gitignore | File | | 58 B | a week ago | a week ago
5 | .vscode | Directory | | 4.1 KB | a month ago | a month ago
...

この作業をおこなうために、lsにコマンドライン引数を渡していないことがわかります。代わりに、Nuが提供するsort-byコマンドを利用して、lsコマンドの出力をソートしています。

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

> ls | where size > 4kb
----+----------------+------+----------+----------+----------------+----------------
# | name | type | readonly | size | accessed | modified
----+----------------+------+----------+----------+----------------+----------------
0 | IMG_1291.jpg | File | | 115.5 KB | a month ago | 4 months ago
1 | README.md | File | | 11.1 KB | 2 days ago | 2 days ago
2 | IMG_1291.png | File | | 589.0 KB | a month ago | a month ago
3 | IMG_1381.jpg | File | | 81.0 KB | a month ago | 4 months ago
4 | butterfly.jpeg | File | | 4.2 KB | a month ago | a month ago
5 | Cargo.lock | File | | 199.6 KB | 22 minutes ago | 22 minutes ago

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

> ps
-----+-------+----------+------+--------------------------------------------------------------------------------
# | pid | status | cpu | name
-----+-------+----------+------+--------------------------------------------------------------------------------
0 | 1003 | Unknown | 0.00 |
1 | 1515 | Sleeping | 0.00 | /usr/lib/gnome-settings-daemon/gsd-screensaver-proxy
2 | 2128 | Sleeping | 0.00 | /usr/lib/gnome-settings-daemon/gsd-screensaver-proxy
3 | 2285 | Unknown | 0.00 |
4 | 8872 | Sleeping | 0.00 | /usr/lib/gvfs/gvfsd-dnssd--spawner:1.23/org/gtk/gvfs/exec_spaw/4
5 | 1594 | Sleeping | 0.00 | /usr/lib/ibus/ibus-engine-simple

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

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

> ps | where cpu > 10
---+-------+----------+-------+-----------------------------
# | pid | status | cpu | name
---+-------+----------+-------+-----------------------------
0 | 1992 | Sleeping | 44.52 | /usr/bin/gnome-shell
1 | 1069 | Sleeping | 16.15 |
2 | 24116 | Sleeping | 13.70 | /opt/google/chrome/chrome
3 | 21976 | Sleeping | 12.67 | /usr/share/discord/Discord

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

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

> date
------+-------+-----+------+--------+--------+----------
year | month | day | hour | minute | second | timezone
------+-------+-----+------+--------+--------+----------
2019 | 8 | 17 | 19 | 20 | 50 | +12:00
------+-------+-----+------+--------+--------+----------

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

> sys
----------+----------+-----------+----------+-----------+-----------
host | cpu | disks | mem | temp | net
----------+----------+-----------+----------+-----------+-----------
[object] | [object] | [3 items] | [object] | [3 items] | [3 items]
----------+----------+-----------+----------+-----------+-----------

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

> sys | get host
-------+------------------+----------+--------+----------+----------
name | release | hostname | arch | uptime | users
-------+------------------+----------+--------+----------+----------
Linux | 5.0.0-21-generic | pop-os | x86_64 | [object] | [1 item]
-------+------------------+----------+--------+----------+----------

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

> sys | get host.users
jonathan

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

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

実際にNuの外で文字列がどのように機能するか見てみましょう。ほとんどのOSに組み込まれているechoコマンドを以前の例の中で実行してみましょう。

> sys | get host.users | echo $it
jonathan

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