💻

macOS の open コマンドに渡すアプリ名をインタラクティブに選択する

に公開
2

macOS の open コマンドに -a オプションを渡すことで、対象のパスを指定した macOS のアプリケーションで開ける。

# カレントディレクトリを Visual Studio Code で開く
open . -a 'Visual Studio Code'

便利かどうかはさておき、この 'Visual Studio Code' の部分をインタラクティブに選択できないか試行錯誤した。

まずは macOS にインストールされているアプリを列挙するために、/Applications フォルダを ls コマンドで探索する apps コマンドを考える。

alias apps='\ls -1 /Applications | fzf'

ls コマンドに対して貼っているエイリアスが影響しないように、ls コマンドをエスケープしている。-1 オプションは man ls の通り、結果を1行毎に表示できる。これは fzf コマンドに渡すためである。

 -1      (The numeric digit “one”.) Force output to be one entry per line.  This is the default when output is not to a terminal.

これで macOS にインストールしてあるアプリ名を列挙し、インタラクティブに選択できる。ここから open コマンドの -a オプションに渡すために、.app という拡張子を sed s/.app// で削る。つまり Visual Studio Code.app という文字列であれば Visual Studio Code のように整形する。そして、そのコマンドの実行結果を open コマンドの -a オプションに渡すことで実現できた。

alias apps='\ls -1 /Applications | sed s/.app// | fzf'
alias app='open . -a "$(apps)"'

# すべて展開した状態
open . -a "$(\ls -1 /Applications | sed s/.app// | fzf)"

アプリ名に半角スペースを含んでいる場合に、そのまま実行しようとするとアプリ名を適切に渡せず、文字列として扱うためシングルクオートで囲んでいた。しかし、中身をそのままの文字列として扱うだけで意味がなく期待通りに動作していなかったが、コメントで指摘いただいた通り、そもそもダブルクオートで "$(apps)" のように評価すれば良い話であった(錯乱)。

GitHubで編集を提案

Discussion

kkddkkdd

こんにちは。
下記は期待通りに動作しました。

$ cod="Visual Studio Code"
$ open -a "$cod" test.txt

しかしながら下記は、シェルの基本に基づき、正常動作しないと思います。

$ open -a $cod test.txt
$ echo 'open -a $cod test.txt' | shellcheck -s sh -
In - line 1:
open -a $cod test.txt
        ^--^ SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean: 
open -a "$cod" test.txt
@1000ch@1000ch

ご助言ありがとうございます。ご指摘の通り、シングルクオートが shell で eval される状況をどうしようかと思っていましたが、そもそもダブルクオートで処理すべきですね。