Background
株式会社AbemaTVでABEMAの広告プロダクト開発チームでSREをしているKosakaと言います。
元々はデザイナー・サーバサイドエンジニアをしていましたが、最近はクラウドネイティブな技術やパブリッククラウドと戯れています。
さて、ABEMAやアメーバをはじめ、サイバーエージェントが運営する各メディアをプラットフォームとした広告プロダクト・広告配信システムを開発しているチームが社内にはいくつかあります。
それらを横軸で束ねる、PTA(Publisher adTech Associations)というアライアンスが立ち上がり、所属エンジニアやビジネス職のメンバーを中心に、広告配信を支える技術や広告業界のドメイン知識に関する情報共有、勉強会、公開イベントなどを定期的に開催しています。
今回はそのPTAのアドベントカレンダー2020のエントリとして小ネタ記事を書きたいと思います。
Introduction
Prerequisites
- この記事の内容は、非エンジニアを含め、全macOSユーザを対象としています
- ちなみにABEMAを含むサイバーエージェントでは、エンジニアの8〜9割ぐらいがMacで開発をしています(デフォルトはMacですが、もちろん選べます)
- 今回の例ではiTermを挙げていますが、iTermはPython APIを提供することでAppleScriptのサポートを無くす方向のようです
- しかしながら、他のアプリケーションでも同じ戦略が使える場合が多いため、適宜読み替えて試してみてください
- Alfredなどのランチャーを使っているとさらに便利かと思います
Goals
- AppleScriptの普及
- 極小かつ繰り返し発生する手作業(micro-toil)に対して、減らせないだろうか?と考えてみるきっかけにして欲しい
- 人々の日々のストレスフルな作業・操作を少しでも減らす
- 1日30秒節約できれば1年間でおよそ3時間の節約になります(映画1本多く観られますね!)
- 現実的には時間的効果は実感できないと思いますが…
- ストレス軽減効果を考えると時間以上にメリットがあるかもしれません
- 何よりも、これが解消できた!という喜び・達成感が大事
Motivation
今回、AppleScriptを使おうと思った動機を以下で述べます。
- マルチディスプレイ環境+複数デスクトップを行き来して作業することが多い
- 既に起動しているアプリケーションの新規ウィンドウを開きたいことが多々ある(ターミナル etc)
このような場合、通常であれば以下のような操作になるかと思います。
説明のために、2つのデスクトップ、デスクトップAとデスクトップBがあるとし、デスクトップAでiTermが開いている状況を考えます。
- デスクトップBで作業中にiTermのウィンドウが欲しくなった(ウェブサイト見ながらコマンド試したいとか、ありますよね?あるんです)
- デスクトップAに移動する(コマンド+TabでもMission Controlでもなんでもいいです)
- 既に開いているiTermウィンドウにフォーカス
- 新規ウィンドウを開く
- 新規ウィンドウをデスクトップBに持っていく
これが1日に何度もあると操作が面倒になってきます。コンピュータを使っているのだから、こういうのは機械がやって欲しいものです。
そこでAppleScriptの出番です。
今回は、上で述べた手順の2〜5を無くしてしまおうと思います。
AppleScript
AppleScriptはSystem 7といういにしえのOSで採用されたMac用のスクリプト言語です。
アプリケーション操作の自動化などを行うことができます。構文は若干古い印象を受けますが、今回のようなライトな使用目的に限れば、学習コストはかなり小さく済むのではないでしょうか。
macOSに標準でインストールされているスクリプトエディタで記述するのが一般的かと思います。もちろん、使い慣れたエディタを使うこともできます。VSCodeのプラグインもあります。
完成したスクリプトは.app形式にビルドすることもできます。
Hands-On
さて、ここから実際にAppleScriptを使って実装をしていきます。
まずはスクリプトエディタを起動します。ユーティリティの中にあると思います。
ランチャーからの起動なら一瞬です。
以下の操作の自動化を実装していきます。
- iTermが起動していなければ起動する
- iTermの新規ウィンドウをデフォルトプロファイルで作成する
- 作成したウィンドウをフォーカス状態にする
結論から掲載してしまいますが、以下のようなコードになります。
if application "iTerm" is not running then
activate application "iTerm"
else
tell application "iTerm"
create window with default profile
activate
end tell
end if
スクリプトエディタの実行ボタンを押すとiTermの新規ウィンドウが開きます。
ここで特に注目したいのが、create window with default profile
の部分です。
「iTermのデフォルトのプロファイルで新規ウィンドウを作る」という命令ですが、これはiTerm固有の命令です。
2行目のactivate application "iTerm"
などはmacOSのGUIアプリケーションに共通した命令であり、AppleScriptのリファレンスで引くことができます。
しかし、iTerm固有の命令にどのようなものがあるのかをどのように知ることができるのでしょうか?
サポートの充実したアプリケーションであれば、ウェブ上でドキュメントを公開している場合もありますが、公開されていない場合も多いです。また、AppleScriptをサポートしていないアプリケーションもあります。
AppleScriptをサポートしているアプリケーションは/Applications/<app name>.app/Contents/Resource
配下に<app name>.sdef
という辞書ファイルを持っています。
スクリプトエディタのFile > Open Dictionary
メニューでsdefファイルをもつアプリケーションの一覧を見ることができ、ここから目的のアプリケーションを選択することで開くことができます。
言い換えれば、このリストにあるアプリケーションはAppleScriptに対応しているということです。
iTermのものもありました。
これによると、command <text>
でシェルにコマンドを渡して実行することができそうですね。そこで、開いたiTermの新規ウィンドウでvimを実行してみたいと思います。
次のようにスクリプトを修正します。
if application "iTerm" is not running then
activate application "iTerm"
else
tell application "iTerm"
create window with default profile command "vim"
activate
end tell
end if
実行ボタンを押すと、vimを起動した状態のiTermの新規ウィンドウが開きました!
辞書ファイルの次の項目を見ると、write
コマンドというものもあります。これにテキストを渡すとシェルでの入力を模倣できるようです。少し複雑な操作も自動化できそうですね。そこで、~/Desktop/vim
フォルダに日時を名前に持つテキストファイルを作成し、それをvimで開くという操作をさせてみました。
if application "iTerm" is not running then
activate application "iTerm"
else
tell application "iTerm"
set w to create window with default profile
activate
tell current session of w
write text "mkdir -p ~/Desktop/vim && vim ~/Desktop/vim/`date +%Y%m%d%H%M%S`.txt"
end tell
end tell
end if
とっさにメモを取りたいときに役立ちそうです!
いろいろ試してみたくなるところですが、一旦、iTermの新規ウィンドウを開くスクリプトに戻ります。
AppleScriptの項で述べた通り、スクリプトは.app形式にビルドすることができます。File > Export
でapp形式で書き出すだけなので、お手軽です。Windowsで言うところのbatファイルのようなものでしょうか。
書き出したファイルにNewiTermWindow.app
などと名前をつけて、パスが通っているところに置いておけば、Alfredなどのランチャーから実行することができ、書き出したアプリケーションファイル名の先頭数文字、この場合ではnew
と入力するだけで、現在のデスクトップにiTermの新規ウィンドウを作成することができます。
これにより目的は達成されました!お疲れ様でした。
Conclusion
まとめです。
存在すら知られていないかもしれないAppleScriptですが、かゆいところに手が届くので、同じ操作を繰り返しているな?と気づいた際に思い出してもらえれば嬉しいです。
年末年始のステイホーム時間で遊んでみてください!
SREとしてチームのtoil削減も考えなければいけませんが、自分の作業環境におけるmicro-toilとそれに伴うストレスを無くすことも必要なことだと思っています。
広告の話を全くしませんでしたね…。いいんでしたっけ?