らぼるてっく。

てっくてっく歩いてっく。

Babashkaを使えばClojureでShell Script作れるよ

こんにちは。ラボルのバックエンドエンドエンジニアの中垣です。

この記事はClojureを知ってる前提で書いてます。Clojureを知らない人はClojureをやってみるのをおすすめします。楽しいですよー。最初はBrave Clojureで基本を学べます。

この記事では、ClojureでBabashkaと呼ばれるツールを使用してBashスクリプトを書く方法を紹介します。普段Bashスクリプト書かないけどClojure好きな人におすすめです。Clojureを使う機会が増えますよ。

僕はBabashkaを使ってこんな感じなことをやってます。

  • Build toolでやっていること
    • 開発環境のセットアップ(npm installとか)
    • 自動テストの実行
    • デプロイするスクリプト
  • その他Bashでやりそうなこと
    • SSHでPortForwardingしてるプロセス全てを停止するスクリプト
    • Gitで管理された.zshrcなどの設定ファイルをPCに適応させるスクリプト

TOCです。

Babashkaで何ができるのか

実際に試してみると理解しやすいので、まずBabashkaをインストールしてみてください。インストール手順はこちらにあります。

https://book.babashka.org/#_installation

ここに書いてあることは大体BabashkaのDocumentationにあるので詳細が知りたい人は見てみてください。

基本操作

例で色々デモしていきます。例で使ってるディレクトリーはこうなってます。

.
├── a.txt
├── b.txt
├── bb.edn
├── c.txt
└── sample.clj

Terminal上でClojureコードを実行する。

Babashkaはbbのコマンドで実行できます。

bb '(+ 1 2 3)'

結果: 6

Shell commandの結果を使ったClojureコードを実行する

bbコマンドに-iのOptionをつけるとStringで引数を受け付けられます。受け取った引数は*input*変数に代入されます。

ls | bb -i '(prn *input*)'

結果: ("a.txt" "b.txt" "bb.edn" "c.txt" "sample.clj")

.cljファイルをbashで実行する

sample.cljのようなClojureのファイル内のコードも実行出来ます。

;; sample.clj
(prn (+ 1 2 3))
bb sample.clj

結果: 6

REPLも使えるのでセットアップしたらもっとBabashkaが楽しくなります。

https://book.babashka.org/#repl

Libraryの使用

Clojureではclojure.stringclojure.java.ioとかよく使いますよね。Babashkaでも使えるんです。

;; sample.clj
(require '[clojure.string :as s])

(->> (slurp *in*) 
     ;; cli上じゃなくて.cljファイルの場合、
     ;; *input*じゃなくて(slurp *in*)を使った方がいいらしい
     (s/split-lines)
     (first)
     (prn))
ps aux | bb sample.clj

結果:

"USER               PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND"

ファイル操作やShellコマンド実行などBabashka特有のものもあります。

(require '[babashka.process :refer [sh]]
         '[clojure.string :as s])

(->> (:out (sh "ls"))
     (s/split-lines)
     (filter #(re-find #"clj" %))
     (prn))
bb sample.clj

  結果: ("sample.clj")

TaskRunnerでプロジェクトごとのタスク定義

GradleなどのBuild toolではタスクを定義できます。Babashkaでも同じようなことができます。

プロジェクトのディレクトリー直下にbb.ednのファイルを置いたらそこでタスク定義できます。

例:

;; bb.edn
{:tasks
 {:requires ([babashka.process :refer [sh]])
  list-clojure-files (->> (:out (sh "ls"))
                          (s/split-lines)
                          (filter (fn [file]
                                    ;; Task Runnerでは#記号が使えない
                                    ;; そのため、#(foo %)のような無名関数は使えない
                                    (re-find (re-pattern "clj") file)
                                    ;; regexの#"foo"も使えないため、re-patternを使う
                                    ))
                          (prn))}}
bb list-clojure-files

結果: ("sample.clj")

Babashkaの使いどき

個人的にはBabashkaでスクリプト作成回りは大分快適になりました。Bashスクリプトの作成が楽しくなり、メンテナンスもしやすくなりました。なのでClojureのプロジェクトであればどんどん採用していくのをおすすめします。

でも気をつけないといけないことは、BabashkaはClojureでBash scriptを書けるようになるけどClojureを知らない人からすると何もメリットがないということです。むしろClojure読めなくて不満が溜まるかもしれないです。まずはチームをClojureプログラマーにCovertしてから導入した方がいいですね。

おわりに

ラボルでは、エンジニアを積極採用中です。1、2年目のエンジニアから経験豊富なテックリードやエンジニリングマネージャーまで、興味がある方はぜひご応募ください!!

labol.co.jp