目次

この記事は筆者 syui による、AppleScript に関する Tips をまとめたものになります。AppleScript の書き方ではなく、主に Example を紹介する内容になります。

具体的には、AppleScript を ShellScript から実行したり、ターミナル・アプリとの連携を主体とする内容になります。

最後に、著者はコンピュータについては全くの初心者です。多分、はじめてコンピュータを触ったばかりの人よりも遥かに劣るレベルだと思われます。その点は考慮していただけると幸いです。一緒に AppleScript を学習していきましょう。

はじめに

AppleScriptについて

AppleScript は、Mac で起動する GUI(グラフィック・ユーザーインターフェース) アプリやウィンドウなどを操作することに使える補助的なスクリプトです。

著者は CLI(コマンドライン・インターフェイス) に生息しているため、これを CLI から実行するコンセプトで書いていきます。

その他の内部的なシステムの変更はコマンドで行えます。

この記事では直接 AppleScript と関係するわけではありませんが、いくつか Mac を操作するコマンドを解説することにします。

方針について

当記事の方針の一つは、著者が後々利用しやすいように作っていく方針です。

一部、表現等に正確ではないものも含まれると思いますが、この記事では正確さよりも分かりやすさを重視します。もし正確な情報が欲しければ、公式ドキュメントを参照指定ください。

なお、内容が充実してきたら別ページにも保存するかもしれません。

AppleScript入門

AppleScriptの作成と実行

まずは具体例から見ていきましょう。そちらのほうが早いです。

拡張子はなんでも良いのですが、公式エディタアプリは.scptなどを読みます。

AppleScript

chrome_get_url.scpt

#!/usr/bin/osascript
tell application "Google Chrome" 
	get URL of active tab of first window
end tell

これは、Google Chromeで開いているタブのURLを取得するスクリプトです。

作成したAppleScriptには実行は権限を渡して以下のように実行できます。

$ chmod +x chrome_get_url.scpt
$ ./chrome_get_url.scpt
https://syui.gitlab.io

Shell

AppleScriptをShellから実行するには、osascript -eを使います。

$ osascript -e 'tell application "Google Chrome" to get URL of active tab of first window'

ShellScript

ShellScript内で実行するにはosascriptから<< EOFを使います。

chrome_get_url.scpt

#!/bin/zsh
osascript << EOF
	tell application "Google Chrome"
		get URL of active tab of first window
	end tell
EOF

or

cat << EOF | osascript -
	tell application "Google Chrome"
		get URL of active tab of first window
	end tell
EOF

ここで、ShellScript内で実行するメリットを一つ紹介しておきます。それは、引数が使いやすいからです。例えば、以下のように引数を$1などから取りやすいのです。

iterm_key.sh

osascript << EOF
tell application "iTerm"
    activate
    tell application "System Events"
        delay 0.1
        keystroke "$1"
    end tell
end tell
EOF

これは、iTermに特定のキー(引数1)を入力するスクリプトです。ここではaを入力させています。

$ chmod +x iterm_key.sh
$ ./iterm_key.sh a
a

Example

Ctrlキーを使った入力をアプリに送る

#!/usr/bin/osascript
tell application "iTerm"
    activate
    tell application "System Events"
        delay 0.2
        keystroke "v" using {command down}
    end tell
end tell

特定のアプリのWindowの情報を取得する

#!/usr/bin/osascript
tell application "iTerm"
	get id of every window
end tell

or

$ osascript -e 'tell application "System Events" to get properties of first window of application process "iTerm2"'

特定のアプリのWindowを選択する

pecoを使ってiTerm2のウィンドウを選択するスクリプトです。

#!/bin/zsh
i=`osascript -e 'tell application "iTerm" to get id of every window'
i=`echo "$i"|tr , '\n'|tr -d , |cut -d '-' -f 2|peco`
osascript <<EOF
	tell application "iTerm" to select window $i
EOF

iTerm2のウィンドウサイズを変更する

まずはコマンドを使って変更したいウィンドウサイズにしておきます。なぜなら、そこからサイズ情報を取得するからです。その後、以下のスクリプトを実行します。

#!/bin/zsh
i=`osascript -e 'tell application "System Events" to get properties of first window of application process "iTerm2"'`
i=`echo "$i"| tr ":" "\n" | grep -A 1 -e position -e size|awk "NR==2;NR==5"`
export a=`echo "$i"|awk "NR==1"|cut -d , -f 1-2`
export b=`echo "$i"|awk "NR==2"|cut -d , -f 1-2`
echo $a
echo $b

次に、出力された情報を使って以下のスクリプトを実行します。なお、process "iTerm2"になっていることに注意。application "iTerm"と指定することとの違いです。

#!/bin/zsh
osascript <<EOF
	tell application "System Events"
		set position of first window of application process "iTerm2" to {$a}
		set size of first window of application process "iTerm2" to {$b}
	end tell
EOF

or

#!/bin/zsh
osascript <<EOF
	tell application "System Events" to tell application process "iTerm2"
		set position of window 1 to {$a}
		set size of window 1 to {$b}
	end tell
EOF

or

#!/bin/zsh
osascript <<EOF
	tell application "System Events"
		tell application process "iTerm2"
			set position of window 1 to {$a}
			set size of window 1 to {$b}
		end tell
	end tell
EOF

基本的には、それぞれのディスプレイによってウィンドウサイズは変わってくるのでtopleftなど定型情報を保存しておき、適時、pecoなどから選択できるようにしておくと便利です。

また、同じ動作をするスクリプトでも書き方は様々です。

これは、個人の好みにもよりますが、個人的には一番上の書き方が好きです。しかし、一般的に好まれるのは一番下の書き方でしょう。

できる限り、再現性及び再利用を考慮した上で書くようにすればいいと思います。

iTermのウィンドウ透過度を設定する

まず最初に透過設定をONにしています。次に、透過度を設定する処理です。この方法はiTerm3に対応しています。具体的には、current terminalwindow 1に変更します。

#!/bin/zsh

osascript <<EOF
tell application "iTerm"
  if the transparency of the current session of window 1 > 0 then
    set the transparency of the current session of window 1 to 0
  else
    set the transparency of the current session of window 1 to 1
  end if
end tell
EOF

osascript <<EOF
tell application "iTerm"
	tell current session of first window
      set transparency to 0.3
    end tell
end tell
EOF

VLCのウィンドウを複数操作する

VLCのウィンドウは非常に厄介なことになっており、window idも一つしかありません。したがって、pidから操作していかなければなりません。

#!/usr/bin/osascript
-- http://stackoverflow.com/questions/22940975/opening-multiple-windows-with-applescript
set WIN_POSITIONS to {{1366,239}, {2326, 240}}
set WIN_SIZES to {{960,598}, {960, 528}}
tell application "System Events"
    set vlcPids to get the unix id of every process whose name is "VLC"
    set winNdx to 1
    repeat with vlcPid in vlcPids
        set haveWin to false
        tell (first process whose unix id is vlcPid)
            repeat with i from 1 to 25 # times out after 25 * .2 == 5 secs.
                if (count of windows of it) > 0 then
                    set haveWin to true
                    tell front window of it
                        set position to item winNdx of WIN_POSITIONS
                        set size to item winNdx of WIN_SIZES
                    end tell
                    exit repeat
                end if
                delay 0.2 # no window yet; sleep some and try again
            end repeat
        end tell
        if not haveWin then error "VLC instance " & vlcPid & " unexpectedly did not create a window within the timeout period."
        set winNdx to winNdx + 1
    end repeat
end tell