エンジニアのはしがき

プログラミングの日々の知見を書き連ねているブログです

iTerm2でよく叩く複数のコマンドを一括実行させてみる

macOSのターミナルで有名なiTerm2。

iterm2.com

実務でよくお世話になっているんですが、頻繁に叩く複数のコマンドを予めPythonスクリプトに記述しておいて一括実行させることもできます。 やってみて結構便利だったのでご紹介します。

Pythonスクリプトを新規作成する

まずはiTerm2のメニューからScripts > Manage > New Python Scriptを選択し、~/Library/Application Support/iTerm/Scripts配下に任意の名前でpyファイルを新規作成します。 ファイル作成前にテンプレのコード生成のためのウィザードが表示されますが、後で修正できるので任意のものを選択して問題ないです。

Pythonスクリプトを編集する

~/Library/Application Support/iTerm/Scripts配下に作成したpyファイルを開いて、iTerm2で実行する処理を記述していきます。

下記はタブを3つ開いて、それぞれのタブでコマンドを実行するスクリプトです。

import iterm2

num_tabs = 3

async def main(connection):
    app = await iterm2.async_get_app(connection)
    window = app.current_terminal_window

    if window is not None:
        await interrupt_sessions(window)

        await create_tabs(window, num_tabs)

    tabs = window.tabs
    for i, tab in enumerate(tabs[:3]):
        session = tab.current_session
        if session is not None:
            match i:
                case 0:
                    await tab.async_set_title("workspace/hogefuga: npm run")
                    await session.async_send_text(f'cd ~/workspace/hogefuga\n')
                    await session.async_send_text(f'npm start\n')
                case 1:
                    await tab.async_set_title("workspace/hogefuga/foobar: npm run")
                    await session.async_send_text(f'cd ~/workspace/hogefuga/foobar\n')
                    await session.async_send_text(f'npm start\n')
                case 2:
                    await tab.async_set_title("gradlew bootRun")
                    await session.async_send_text(f'cd ~/workspace/hogefuga\n')
                    await session.async_send_text(f'./gradlew bootRun\n')
        else:
            print("No current window")

async def interrupt_sessions(window):
    for tab in window.tabs:
        session = tab.current_session
    if session is not None:
        await interrupt_session(session)

async def interrupt_session(session):
    await session.async_send_text('\x03')

async def create_tabs(window, num_tabs):
    tabs = window.tabs
    for i in range(len(tabs), num_tabs):
        await window.async_create_tab()

iterm2.run_until_complete(main)

caseで分岐させてそれぞれのタブに対してsession.async_send_textを実行してコマンドを実行しています。 末尾の"\n"はエンターキーでのコマンド実行に相当します。

tab.async_set_titleではタブに表示される名前を固定化しています。デフォルトだとiTerm2はコマンドの実行状況によってタブ名が切り替わってしまうので見にくい場合は固定化するのがおすすめです。

なお、このスクリプトでは冒頭で実行中のコマンドを中断させるinterrupt_sessionを実行していますが、タブに対してCtrl+Cに当たる"\x03"を送信することで中断を実現しています。

Pythonスクリプトを実行する

さて、pyファイルが作成できたらiTerm2のメニューのScriptsに作成したファイルが新たに追加できるようになっているので実行してみましょう。

前のセクションで作成したpyファイルが実行され、別々のタブでコマンドが実行されるはずです。