1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

備忘録: MacOS のコマンドラインからのテキストファイルの開き方

Last updated at Posted at 2020-02-26

Terminal.app からテキストエディターを開く方法を試してみました. ダブルクリックで開くアプリを環境設定用のアプリの中から起動したくて, アプリの起動法を調べ始めた中のことです. インターネットで調べていて open -a myapp.appopen -a myapp のどちらがよいのか混乱してきたということがきっかけで現状調査を思い立ちました.

調査結果の概要

  • 標準ソフトは文献によくでてくる open -a TextEdit などで大丈夫です.
  • 正式っぽい使い方は open -b com.apple.TextEdit などのように -b オプションを使う起動の仕方です.
  • アプリのデバッグなどで複数バージョンの動作を比較する状況では, フルパス名を指定して open -a /Appliations/SageMath-9.0.app などとします.
  • フルパス名に日本語が含まれている場合も, フルパス名でアプリ名を指定する方法は大丈夫です.
  • 一部のアプリでは, open -a SageMath-9.0 という起動の仕方ができません.
  • open -a TextEdit/Applications/TextEdit.app/Contents/MacOS/TextEdit でアプリの挙動に差異があります.

~/MyAppli.app~/マイアプリ.app をデバッグ中で複数バージョンの動作比較を行なっている状況で, デバッグ対象をダブルクリックと同等の動作で起動したい場合について表にまとめておきます.

コマンド 可否
open -a TextEdit
open -b com.apple.TextEdit
open -a ~/MyAppli.app
open -a MyAppli.app 可?
open -a MyAppli 不可
open -a ~/マイアプリ.app
open -a マイアプリ.app 可?
/Applications/TextEdit.app/ Contents/MacOS/TextEdit 不可
~/MyAppli.app/Contents/MacOS/MyAppli 不可

(長い絶対パス名を表に押し込むために途中にスペースを入れてありますがテストしたときの絶対パス名は途中にスペースも改行も入れていません.)

open コマンドで自作アプリを起動する場合には, 同じベースネームのアプリが複数配置してある状況がありますので, アプリ開発の中の動作テストの場面で, 起動中のアプリからそのアプリの絶対パスの情報を調べるテクニックが欲しくなります. これは将来の調査課題として残りました. 想定する状況だけ記しておきます.

  • 同じバージョンのコピーを複数のフォルダーに配置してしまった場合
  • 異なるバージョンに同じベースネームを付けてしまった場合.

参考資料

2017年04月14日付の macOS Mojave 10.14.6 の man-page の open の記述と 寝坊した さんの「プログラミングと海外移動の情報マガジン」のページ 便利に使えるMacのopenコマンド を参考にしました.

実際に試した使用環境

バージョン情報は以下の通りです.

  • macOS Mojave 10.14.6
  • CotEditor 3.8.4

動作テストの仕方

ここでは , カレント・ディレクトリー内に MyTextFile.txt というファイルを作成してある状況で MyTextFile.txtTerminal.app 内の bash から開く例を調べます.

指定するアプリは macOS 標準の TextEdit.app です.
Finderシステム環境設定言語と地域 の設定によっては TextEdit, テキストエディット, テキストエディット.app などと表示されていると思います.

一時的に他のアプリを例として挙げる場合も出てきます.

アプリを絶対パスで指定してテキストファイルを開く

絶対パス名 (バックスラッシュで始まるフルパスネーム)による open コマンドの起動の仕方が man-page に記載されていますので, なぞってみます.

コマンド:

myhome$ open -a /Applications/TextEdit.app MyTextFile.txt

動作: TextEdit.appMyTextFile.txt を開いて前面に出てきます.

man-page にある例から少し起動の仕方を変更して試行錯誤した結果, 注意点がでてきました.

注意点 (できないこと):

  • ファイル拡張子 .app を取ると起動できません.
  • open-a の引数について相対パスとベースネームを区別しているようです. 例えば , /Applications にいるときに open -a ./TextEdit.appopen -a TextEdit.app で挙動が違います.
  • アプリのパスに相対パスは使えないようです.
  • アプリの名前にシェルの alias は使えません.
  • アプリの名前に Locale の表示名は使えません. (オプション -a の引数の中で /Applications/アプリケーション に変えたり TextEditテキストエディット に変えたりすると, 起動できません.)

注意点 (できること):

  • シェルの変数に絶対パス名を入れておいて展開させることは可能です. (open コマンドに引数を送る前にシェル側で処理する形で使う場合ですので, export などで環境変数にしている変数以外の変数でも問題ありません.)
  • アプリの絶対パス名はアプリの絶対パス名へのシンボリック・リンクの絶対パス名でも構いません.
  • アプリの絶対パス名はアプリの Mac エイリアス (別名 ) の絶対パス名でも構いません.
  • 下記の 3通り全てについて, アプリの絶対パス名の後ろにスラッシュ / を追加して構いません.
    • アプリのパス名を直接使う場合, シェルの変数を展開して open コマンドに送る場合
    • アプリへのシンボリック・リンクの絶対パス名を使う場合
    • アプリへの Mac エイリアスの絶対パス名を使う場合

注意点 (できること) の例1.

myhome$ te2day=/Applications/TextEdit.app/
myhome$ open -a $te2day    MyTextFile.txt

注意点 (できること) の例2.

myhome$ open -a /Applications/TextEdit.app/    MyTextFile.txt

注意点 (工夫すればできること): アプリのファイル名に空白文字が含まれている場合は, 引用符かバックススラッシュによるエスケープを使って下さい. 下記の例はテキストファイルを開く例ではありませんがアプリの絶対パス名の扱いは同じです.

myhome$ open -a "/Applications/Font Book.app"
myhome$ open -a '/Applications/Font Book.app'
myhome$ open -a /Applications/Font\ Book.app

アプリをベースネームで指定してテキストファイルを開く

ベースネームはパス名からフォルダー名をはずしたものという雰囲気のものです. /Applications/Utilities/Terminal.app のベースネームは Terminal.app です. 技術的には, /Applications/Utilities/Terminal.app 自体がフォルダーだという事情で表現が難しいとろこですが

myhomt$ basename /Applications/Utilities/Terminal.app/
Terminal.app
myhome$ dirname /Applications/Utilities/Terminal.app/
/Applications/Utilities

とうコマンドの引数を変えて試すとわかるbasenamedirname の動作に準拠します.

/Applications/TextEdit.app のベースネームは TextEdit.app です.

myhome$ open -a TextEdit.app MyTextFile.txt

動作: TextEdit.appMyTextFile.txt を開いて前面に出てきます.

注意点 (できないこと):

  • アプリのベースネームの後ろにスラッシュ / を付けると起動できません.
  • アプリのシンボリック・リンクを /Applicationsやカレント・ディレクトリー に置いている場合でも , シンボリック・リンクのベースネームによってアプリを指定して起動することはできません.
  • アプリのMac エイリアスを /Applicationsやカレント・ディレクトリー に置いている場合でも , Mac エイリアスのベースネームによってアプリを指定して起動することはできません.

注意点(できてしまうこと):

  • アプリのベースネームを小文字にしても起動できてしまいます. (もしかすると , case-insensitive file system の問題点かもしれません. case-sensitive file system では大文字と小文字が区別されて, 下記のおかしな例が不可になるかもしれません.)
悪い例 myhome$ open -a textedit.app MyTextFile.txt

疑問点:

  • MacOS のアプリは XXXX.app/Contents/Info.plist の Bundle Name や Display Name というエントリーで名前を登録しています. この名前を使うのが MacOS Classic からの伝統につながるはずですが, 自作アプリのファイル名を変更して試してみると, アプリのファイル名のベースネームが open コマンドのアプリ名として通用しているようです. (CFBundleNameがあって, CFBundleDisplayName がない自作アプリを Automator で作成して調べました.)
  • インターネットで open コマンドの使い方を調べていると, 「アプリのフォルダーに移動してから , open -a アプリのベースネーム を実行する」という内容の記述や「アプリが /Applications フォルダーにあるときは, アプリをベースネームで指定することができる」とう内容の記述があります. ところが, 自作アプリで調べてみると, カレント・フォルダーでもなく /Applications フォルダーでもない場所に置いてあるアプリでもベースネームで指定することができるようです. MacOS X のバージョンが変わってきた中で動作が変化してしまったのかもしれません . セキュリティー対策からすると怖い方向の変化です.

アプリのベースネームから拡張子 .app をはずした名前でアプリを指定テキストファイルを開く

/Applications/TextEdit.app を例にするとベースネームは TextEdit.app で拡張子 .app をはずした名前は TextEdit です.

myhome$ open -a TextEdit  MyTextFile.txt

動作: TextEdit.appMyTextFile.txt を開いて前面に出てきます.

注意点 (なぜかできること):

  • アプリの名前を TextEdit/ としても起動することができます.
  • インターネットで open コマンドの使い方を調べていると, .app を省略して良いというページと省略してはいけないというページが両方出てくると思います. TextEdit でも今回試した自作アプリでも .app を省略した形で open コマンドが使えるのですが, SageMath-9.0.app の場合は open -a SageMath-9.0open -a SageMath-9 も不可でした. ベースネームの中の .app を省略できる条件は判然としないところがあります. もしかすると SageMath を複数バージョン置いている状態がトラブルを起こしているのかもしれません. (ここの調査はTextEdit.app 以外はファイルを開く形ではないアプリの起動で行いました.)

注意点 (できないこと ):

  • アプリの名前にシンボリック・リンクや Mac エイリアスのベースネームを使うことができない状況は拡張子 .app をはずしても変わりません.

アプリを Bundle Identifier で指定して起動

アプリの Bundle Identifier はアプリの Info.plist で宣言してある名前で MacOS の中でのアプリの正式名称です. 調べ方は, 後で紹介します. ここでは, TextEdit.app のBundle Identifier com.apple.TextEdit を使います.

まず, man-page にある例をなぞります.

myhome$ open -b com.apple.TextEdit MyTextFile.txt

動作: TextEdit.appMyTextFile.txt を開いて前面に出てきます.

MacOS はアプリのデータベースを作って, ファイルとアプリの関連付けやアプリの起動を行っています. そのデーターベースを調べると
com.apple.texteditcanonical id: として載っています. canonical は「標準形に変換してから比較する」というときの「標準」に近い言葉ですので, Bundle Identifier として, com.apple.textedit も試しました.

myhome$ open -b com.apple.textedit MyTextFile.txt

英字を小文字に変換する標準化が介在していると考えて

myhome$ open -b com.apple.Textedit MyTextFile.txt

も試しました.

どちらも, com.apple.TextEdit の場合と同じ動作でした.

open コマンドのオプションでテキストエディターを指定してテキストファイルを開く

open コマンドに -e オプションを指定すると TextEdit.app でファイルを開きます. -e オプションの代わりに -tオプションを使うとデフォールト・テキストエディターでファイルを開きます. アプリを指定するオプションなしでファイルを開くと, そのファイルに関連付けられているアプリでファイルを開くことになります.

テキストファイルとテキストエディターの関連付けは, テキストエディター 2種 (TextEdit.app, CotEditor.app) を使って MyTextFile.txt に対するファイル個別の関連付けとテキストファイル全般の関連付けの組み合わせ合計 4通りを考えることにしました.

この起動の仕方 3 通りと掛け合わせて 12通りの網羅テストを行いました.
コマンドごとに表にまとめます.

myhome$ open -e  MyTextFile.txt
open -e MyTextFile.txt .txt --- TextEdit .txt --- CotEditor
MyTextFile.txt --- TextEdit TextEdit TextEdit
MyTextFile.txt --- CotEditor TextEdit TextEdit
myhome$ open -t MyTextFile.txt
open -t MyTextFile.txt .txt --- TextEdit .txt --- CotEditor
MyTextFile.txt --- TextEdit TextEdit CotEditor
MyTextFile.txt --- CotEditor TextEdit CotEditor
myhome$ open  MyTextFile.txt
open MyTextFile.txt .txt --- TextEdit .txt --- CotEditor
MyTextFile.txt --- TextEdit TextEdit TextEdit
MyTextFile.txt --- CotEditor CotEditor CotEditor

動作: 以上の 12通のどの場合でも, 表に記載のテキストエディターが MyTextFile.txt を開いて前面に出てきました.

MacOS はインストール直後の状態では デフォールト・テキストエディターが TextEdit.app になっています.

注意点:

  • open コマンドは -a TextEdit とテキストファイルのファイル名の片方なら省略することができますが, 両方省略するとヘルプを表示して終了してしまいます.
  • open -eopen -t はテキストエディターを起動します. このときテキストエディターは新規ファイルの編集ウィンドウで前面に出てきます.

アプリの MacOS 実行形式を直接指定してテキストファイルを開く

アプリの MacOS 実行形式はアプリから相対パス Contents/MacOS/ の位置のフォルダーに入れるのが慣例です. 実行形式のファイル名のベースネームは Info.plist に入っている推測していますが, 調査はまだです.

$ plutil -p /Applications/TextEdit.app/Contents/Info.plist | egrep -e Executable
  "CFBundleExecutable" => "TextEdit"

TextEdit.app の場合は, 下記のコマンドで開始することができます.

myhome$ /Applications/TextEdit.app/Contents/MacOS/TextEdit

動作: TextEdit.app は起動しますが, ウィンドウは前面に出てきません.

注意点:

  • この起動の仕方の TextEdit は挙動不審です. ファイル名を指定した場合, 起動した側のカレント・ディレクトリからではなくホーム・フォルダーから相対的にファイルを探すようです.

MacOS のアプリのデータベース の調べ方と Mac アプリの情報の調べ方

寝坊した さんの 便利に使えるMacのopenコマンド で教わったコマンドの出力から idcom.apple.TextEdit の行を egrep で抜き出してみました.

myhome$ cd  /
myhome$ cd System/Library/Frameworks/CoreServices.framework
myhome$ cd Frameworks/LaunchServices.framework/Support/
myhome$ ./lsregister -dump | egrep -i -e 'id.*com.apple.TextEdit'
	identifier:    com.apple.TextEdit (0x80003de5)
	canonical id:  com.apple.textedit (0x80003de4)
    CFBundleIdentifier = "com.apple.TextEdit";
    "com.apple.application-identifier" = "com.apple.TextEdit";

最初にルートへ cd しているのは, 次の 2行の cd 先を両方とも相対パスにして書式を揃えるためです. egrep のオプション -i は大文字と小文字を同一視する指示です. -e オプションのパラメーターは, egrep にワイルドカードの正則表現 .* を渡すために引用符で囲ってあります. よく考えると, id: com-apple-TextEdit も引っかかる検索になっていますが, 出力に混乱が起きていないので問題ないと思います.

アプリの情報を直接見るには, plutil -p を使います.

myhome$ cd /Applications/TextEdit.app/Contents
myhome$ plutil -p Info.plist | egrep -e CFBundleIdentifier
  "CFBundleIdentifier" => "com.apple.TextEdit"

調査結果

  • 大勢が使っている標準アプリの起動は大勢に合わせておくのが無難で, open -a TextEdit, open -a Terminal などという形で -a オプションが使えます.
  • 正式っぽい使い方は, アプリの名前を書く代わりに -b オプションに続けて Bundle Identifier を書いてアプリを指定する仕方のようです. TextEdit.app を起動するときは open -b com.apple.TextEdit, Terminal.app を起動するときは open -b com.apple.Terminal となるようです.
  • 一方, 自作ソフトや発展段階のアプリで複数バージョンの動作を比較する状況のときはアプリを絶対パス名で指定して open -a /Applications/SageMath-9.0.app とした方がよいようです. この場合は, open -a SageMath-9.0 では起動でこきないことがあるようです. open -b org.sagemath.Sage ではアプリのバージョンが指定できません. 試してみると, LaunchPad に挙がっているバージョンが起動するようですが, SageMath-X.X.app で調べただけの状況です.
  • 複数バージョンでファイル名の中のバージョンナンバーを変えてある場合は, open -a SageMath-9.0.app という起動の仕方でも大丈夫なようです. 他のバージョンが SageMath-8.6.appSageMath-8.9.app というファイル名になっているような場合で調べた結果です.
  • Finder の日本語の表示では TextEdit.appテキストエディットになっていて, /Applications フォルダーは /アプリケーション になっていますが, open コマンドではこの表示名は使えないようです. 文字コードを変えるなどのトリックで表示名による指定ができる可能性については調査していません.
  • アプリのファイル名に日本語を使っている場合も, open -a マイアプリ.appopen -a ~/マイアプリ.app などは使えるようです.
  • open -a TextEdit/Applications/TextEdit.app/Contents/MacOS/TextEdit でアプリの挙動に差異があります.
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?