Terminal Bot / 面倒なTerminal操作を自動化したい!


環境

Mac OS(64bit)
Max8(https://cycling74.com/downloads)

概要

Maxを使ったターミナルをコントロールする便利なBotパッチです。長いターミナルのコマンドをワンクリック化したり、複数サーバーを同時にコントロールするような複雑な工程、またサーバーのログインをまたいだ処理などをワンクリック化できます。

terminalbot / download
https://github.com/sw-sw-sw/terminalbot

なぜ作ったか?

アプリ用サーバーや、ディープラーニングのGPUサーバーインスタンスをコントロールするとき、毎回、長い呪文のようなコマンドをドキュメントで確認したり、打ち続けるのに徒労を感じていました。Maxでそれらのプロセスを事前登録して、自動化できないかと思いつくってみました。

アプローチ

Max用にはshellというサードパーティーのパッチがあります。
https://github.com/jeremybernstein/shell
ただ出力が出なかったり、いろいろなクセがあるため上記の目的には使えませんでした。そこで、applescriptを中継して、mac標準のTerminalをダイレクトにコントロールする方法でやってみました。

terminalが立ち上がります。

こんなときに便利

  • さまざまなコマンドをMaxのパッチ上に並べておくと、ワンクリックで実行できます。google cloud platformのsdkのコマンドなど、コマンドやパスを入力するのも時間がかかるので便利。

  • タイマーを組んでおけば、所定の時間にサーバーを起動、シャットダウンできます。GCPのインスタンスは、使わなくても立ち上がっていると課金されてしまうので節約になります。

  • サーバーのログインをまたぐ作業など、バッチファイルにまとめられない作業を一括操作できます。(ログインするのに必要な時間をdelayパッチなどで設定しておくことで、ログインしてから操作するようなプログラムもできます。)下記は、朝、10時になったら、gcpのGPUインスタンスを立ち上げて、sshのポートフォワーディングでログインし、devフォルダーに移動し、仮想環境を立ち上げてからjuputer labを実行するという一連のコマンド操作をワンクリックにまとめています。

  • 大量のサーバーインスタンスに同じ作業を毎回も実行するようなプロセスも、パッチ化しておくと便利。

Download & 使い方

下記gitからDLしてください。実行パッチmax_terminal.maxpatの中のmax_shellインレットにコマンドを書いたメッセージをつないでクリックするだけです。
https://github.com/sw-sw-sw/terminalbot

  • サンプルコマンドが並んでいるので、適当に編集して使って下さい。
  • プログラムは複数のスクリプトファイルでできています。すべてのファイルを実行パッチterminalbotと同じフォルダーを置いて下さい。

サンプルパッチ / terminalbot.maxpat について

基本的なterminalのコマンド

自分のよく使うコマンドをカスタマイズして使って下さい。

ディレクトリーパス

よく使うディレクトリーパスを並べておくと便利。

インスタンス操作

ディープラーニングで使うGCPのGPUインスタンスのスタート/ストップ、ログイン、仮想環境のオン/オフのコマンド。

仮想環境の操作コマンド

タイマーパッチ

毎日、時間が来たら、サーバーをオンにしたり、オフにしたりします。サンプルパッチterminalbot.maxpatでは、gcpのインスタンスのスタートとストップを制御するように結線しています。

直接入力

フォームに直接コマンドを入力することもできるようになっています。

gitパッチ

gitのコマンド操作を順に並べたパッチです。ファイル名は入力フォームに入れるようになっています。

開発のポイント

興味のある方は、こちらもどうぞ。

  • maxでshellが使えるパッチは、Max用にサードパーティーのshellパッチがいくつか出ていますが、catelina以降使えるのは、こちらだけ。動かないコマンド、パスのズレ、結果の表示がされない、など多少クセがあるようです
     https://github.com/jeremybernstein/shell

  • そこでmaxからosascriptを使って、applescriptを呼び出して、terminallを起動し、コマンドをpipeするようなアプローチを取っています。下記は、shellのモジュールパッチです。主に文字列操作をして、shellにわたすためのosascriptのコマンドを生成処理しています。

下記はapplescriptです。terminalを起動し、受け取ったコマンドの文字列を渡し実行しています。osascriptの引数が、argvに入ります。argvは配列になっていて、item 1 of argvは、一個目の配列の値を示しています。それをcommandをいう変数に入れます。tell applicationでterminalアプリを呼び出します。activateでウィンドウをアクティブにして、一つめのwindowにコマンドを文字列として渡して実行します。

script.scpt

on run argv

    set command to item 1 of argv

    tell application "Terminal"

        activate
        log command
        do script command in window 1

    end tell

end run

応用

同じ考え方でmacのアプリケーションをapplescript経由で、bot操作することができるのでいろいろ応用が効きそう。applescriptは、mac上のアプリケーションやシステムを操作できる便利なスクリプトですが、書式が独特です。ネット上にもいくつか有益な日本語リファレンスがありましたので、興味のある方はご覧になってください。
https://seraphy.hatenablog.com/entry/20100408/p1
https://maku77.github.io/mac/applescript/terminal.html
http://piyocast.com/as/archives/3984
http://java.boy.jp/pukiwiki/index.php?ターミナルをAppleScriptで制御
https://www.it-swarm.dev/ja/macos/applescriptを使用してコマンドと文字列をterminalappに送信する/968622894/