虎の穴開発室ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

モダンなshell 「Nushell」 を触ってみる #虎の穴ラボ Advent Calendar 2023

本記事は 虎の穴ラボ Advent Calendar 2023 13日目の記事です。

  • 本記事のテーマは「モダンなshell 「Nushell」 を触ってみる」です!
  • 前回は浜田さんによる「OpenAPIで試すスキーマ駆動開発」でした。
  • 次回はかなざわさんによる「Hashicorp Vault でのシークレット管理」です。ご期待ください!

こんにちは。虎の穴ラボ株式会社サークルポータル開発チームのY.N.です。

はじめに

VSCodeなどのエディタやGitだとSourcetreeなど、GUIでカバーできるツールも増えてshellを叩かなくても良くなることも多くなってきましたが、
それでも開発を行う上で、shellは必ずといって良いほど使う機会があるかと思います。

そこで、今回はRustで開発されている Nushell というshellを使用して、モダンでイケてるshell環境を構築し、触ってみようと思います。

目次

実行環境

本記事は、MacPCで使用しています。
私の実行環境は下記のとおりです。

  • M2 MacBookPro Ventura13.2.1
  • zsh 5.8.1 (x86_64-apple-darwin22.0)
  • Homebrew 4.0.24
  • warp: 0.2023.06.13.08.03.stable_03

Nushellとは

www.nushell.sh

github.com

NushellはRustで開発されたshell環境です。 構造化されたデータを返すように設計されているため、フィルタやソートなどを非常に簡単にできるようになっています。

例えば、 ls コマンドはzshだと下記のようになります

ls -al
total 8
drwxr-xr-x@ 4 ****  ****   128 Dec  8 17:42 .
drwxr-xr-x  3 ****  ****    96 Dec  8 17:41 ..
drwxr-xr-x@ 9 ****  ****   288 Dec  8 17:41 .git
-rw-r--r--  1 ****  ****  1960 Dec 11 13:38 202312-advent-calendar.md

このデータをフィルタするときは grep コマンドを使用して

ls -al | grep .md

と書く必要があります

これが、Nushellだとどうなるかというと、下記の画像のようになります。

DBのテーブルのような出力になっており、見た目としても見やすい出力結果になっていることがわかります。

また、この結果の名前、種別、権限のみを表示したいと思った場合、

ls -al | select name type mode

というコマンドで表示することができます。

見た目がDBのテーブルのようになっているだけでなく、データ構造やコマンド自体も、DBを操作する感覚で扱うことができるのがNushellの特徴です。

インストールと起動

それでは、早速Nushellをインストールしてみましょう。
Nushellは、homebrewで簡単にインストールできます。

brew install nushell

インストールが完了したら、下記のコマンドで起動することができます。

nu

下記のような表示が出たら、成功です。

     __  ,
 .--()°'.' Welcome to Nushell,
'|, . ,'   based on the nu language,
 !_-(_\    where all data is structured!

Please join our Discord community at https://discord.gg/NtAbbGn
Our GitHub repository is at https://github.com/nushell/nushell
Our Documentation is located at https://nushell.sh
Tweet us at @nu_shell
Learn how to remove this at: https://nushell.sh/book/configuration.html#remove-welcome-message

It's been this long since Nushell's first commit:
4yrs 7months 12hrs 4mins 38secs 64ms 970µs

Startup Time: 90ms 894µs 83ns

実際にコマンドを試してみる

いくつか、私が触っていで便利だと思ったコマンドや、使い方を紹介していきます。

select, where sort-by

先程、出力をフィルタリングするときに select を使用していました。 他にも where を使用して検索ができたり、 sort-by を使用してソートをすることも可能です。

where を使用してpngファイルのみを取り出してみる

> ls | where name =~ '.png' | range 0..5
╭───┬───────────────────────┬──────┬───────────┬──────────────╮
│ # │         name          │ type │   size    │   modified   │
├───┼───────────────────────┼──────┼───────────┼──────────────┤
│ 0 │ 30750866_0001.png     │ file │ 232.4 KiB │ a month ago  │
│ 1 │ 32751345_0001 (1).png │ file │ 191.2 KiB │ 2 weeks ago  │
│ 2 │ 32751345_0001.png     │ file │ 191.2 KiB │ 3 weeks ago  │
│ 3 │ 32751345_0002.png     │ file │ 217.9 KiB │ 2 weeks ago  │
│ 4 │ Nakamura.png          │ file │ 139.3 KiB │ 2 months ago │
│ 5 │ image.png             │ file │ 103.7 KiB │ 5 months ago │
╰───┴───────────────────────┴──────┴───────────┴──────────────╯

sort-by を使用してサイズが小さい順にする

> ls | where name =~ '(?i).png' | range 0..5 | sort-by size
╭───┬───────────────────────┬──────┬───────────┬──────────────╮
│ # │         name          │ type │   size    │   modified   │
├───┼───────────────────────┼──────┼───────────┼──────────────┤
│ 0 │ image.png             │ file │ 103.7 KiB │ 5 months ago │
│ 1 │ Nakamura.png          │ file │ 139.3 KiB │ 2 months ago │
│ 2 │ 32751345_0001 (1).png │ file │ 191.2 KiB │ 2 weeks ago  │
│ 3 │ 32751345_0001.png     │ file │ 191.2 KiB │ 3 weeks ago  │
│ 4 │ 32751345_0002.png     │ file │ 217.9 KiB │ 2 weeks ago  │
│ 5 │ 30750866_0001.png     │ file │ 232.4 KiB │ a month ago  │
╰───┴───────────────────────┴──────┴───────────┴──────────────╯

逆順にしたいときは --reverse を後ろにつけます。

このようにテーブル形式で出力できているものは非常に簡単にフィルタ、ソートができて便利なことがわかります。

describe

describe コマンドでは、コマンドの出力の型を確認できます。

> 45 | describe
int

ls コマンドで確認してみると、

> ls -al | describe
table<name: string, type: string, target: nothing, readonly: bool, mode: string, num_links: int, inode: int, user: string, group: string, size: filesize, created: date, accessed: date, modified: date> (stream)

このように、どんなカラムがあるか、その型は何なのかが確認できるため、
フィルタリング等を行う際にデータ構造がイメージしできないときなどに使うと便利です。

lines

lines コマンドは出力された内容を行ごとに番号を振って構造化してくれます。

例えば、 git branch でブランチ一覧を表示しようとしても、Nushellはこれを勝手に構造化してくれるわけではないので、操作がしづらいものになっています。

> git branch
* 202312-advent-calendar
  main

これを lines を使用することで、データの構造化が可能となります。

> git branch | lines
╭───┬──────────────────────────╮
│ 0 │ * 202312-advent-calendar │
│ 1 │   main                   │
╰───┴──────────────────────────╯

describe した結果も異なっていて、Nushellがデータとして扱える形になっていることがわかります。

> git branch | describe
raw input

> git branch | lines | describe
list<string> (stream)

to json

to json コマンドは、出力した結果をjsonにすることができるコマンドです。

> ls | where name =~ '.png' | range 0..5 | to json
[
  {
    "name": "30750866_0001.png",
    "type": "file",
    "size": 237984,
    "modified": "2023-11-06 13:02:32.725397223 +09:00"
  },
  {
    "name": "32751345_0001 (1).png",
    "type": "file",
    ... 省略
  }
]

ほかにも、CSVやHTML、Markdownに出力することも簡単にできるので非常に便利なコマンドです。
また、from json コマンドもあり、jsonファイルをテーブル形式で表示してくれるコマンドもあります。

gitコマンドのNushell活用例

gitコマンドもNushellを使って構造化することで見やすいデータにすることが可能です。

NushellのCookbookでは、 git log の例を記載してくれているのでこれを試していきます。

通常では下記のようになりますが、これを構造化していきます。

> git log --pretty=%h»¦«%s»¦«%aN»¦«%aE»¦«%aD
7209f41»¦«first commit»¦«Y.N.»¦«****@****»¦«Mon, 11 Dec 2023 17:02:10 +0900

区切り文字を »¦« としているのでこれを split コマンドで分離しています。

> git log --pretty=%h»¦«%s»¦«%aN»¦«%aE»¦«%aD | lines | split column "»¦«"
╭───┬─────────┬──────────────┬───────────────┬───────────────────────────────┬─────────────────────────────────╮
│ # │ column1 │   column2    │    column3    │            column4            │             column5             │
├───┼─────────┼──────────────┼───────────────┼───────────────────────────────┼─────────────────────────────────┤
│ 0 │ 7209f41 │ first commit │ Y.N. │ ****@**** │ Mon, 11 Dec 2023 17:02:10 +0900 │
╰───┴─────────┴──────────────┴───────────────┴───────────────────────────────┴─────────────────────────────────╯

このままだと、カラム名がなく、なんの値かわかりにくいのでカラム名を指定します。

> git log --pretty=%h»¦«%s»¦«%aN»¦«%aE»¦«%aD | lines | split column "»¦«" commit subject name email date
╭───┬─────────┬──────────────┬───────────────┬───────────────────────────────┬─────────────────────────────────╮
│ # │ commit  │   subject    │     name      │             email             │              date               │
├───┼─────────┼──────────────┼───────────────┼───────────────────────────────┼─────────────────────────────────┤
│ 0 │ 7209f41 │ first commit │ Y.N. │ ****@**** │ Mon, 11 Dec 2023 17:02:10 +0900 │
╰───┴─────────┴──────────────┴───────────────┴───────────────────────────────┴─────────────────────────────────╯

日付が文字列なので、ソートしやすいように日付型に直します。

> git log --pretty=%h»¦«%s»¦«%aN»¦«%aE»¦«%aD | lines | split column "»¦«" commit subject name email date | upsert date {|d| $d.date | into datetime}
╭───┬─────────┬──────────────┬───────────────┬───────────────────────────────┬─────────────╮
│ # │ commit  │   subject    │     name      │             email             │    date     │
├───┼─────────┼──────────────┼───────────────┼───────────────────────────────┼─────────────┤
│ 0 │ 7209f41 │ first commit │ Y.N. │ ****@**** │ an hour ago │
╰───┴─────────┴──────────────┴───────────────┴───────────────────────────────┴─────────────╯

こんな感じでgitコマンドの出力もうまく整形することで非常に扱いやすい形にすることができました。

使ってみた感想

私がしばらくNushellを使ってみた感じとしては、とても便利なコマンドが豊富で使いこなせば使いこなすほど効率的に使えそうだなと感じました。

不便に感じた点としては、下記が気になるかなとも思いました。

  • 補完がzsh等の他のシェルと比べると弱い時がある
    → gitコマンド等はbranch名を補完してくれたりしますが、nushellではデフォルトで補完をしてくれないので、設定をする必要があります。
  • コマンドが長い
    → こちらもaliasでどうにかこうにかできればある程度の改善が望めるかもしれません。
  • aliasの設定が難しい(パイプを使うコマンドのaliasがまだ私は実現できていません)

調べたところ、下記のリポジトリでnushell公式が補完用設定ファイルや、alias用の設定ファイルを出してくれているので、これを適用すると改善できるかもしれません。

github.com

まとめ

今回は、Nushellを触ってみて便利なコマンドや使い方を紹介してきました。
まだまだ、使いこなせていない部分も多かったり、Nushell自体も未完成な部分があって安定しているshellではありませんが、
頻繁にリリースがあるので、今後の機能拡充が楽しみなshellだなと感じています。

この記事を読んで気になっていただけたら、ぜひNushellを触ってみていただけると幸いです。

採用情報

虎の穴では一緒に働く仲間を募集中です!

この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧下さい。

カジュアル面談やエンジニア向けイベントも随時開催中です。ぜひチェックしてみてください。 toranoana-lab.co.jp