ファイル名を渡してアプリケーションからウィンドウを閉じるにはどうすればよいですか?

ファイル名を渡してアプリケーションからウィンドウを閉じるにはどうすればよいですか?

Mac OS X の Preview アプリケーションに特定のウィンドウを閉じるように指示する Applescript ベースのシェル コマンドを作成しようとしています。

#!/bin/sh

osascript <<EOF
tell application "Preview"
   close "$1"
end tell
EOF

しかし、これは機能しません。エラーメッセージが表示されます

25:52: execution error: Preview got an error: "musixdoc.pdf" doesn’t understand the close message. (-1708)

関連する質問:.bash_profile で定義されたエイリアスを使用して、コマンド ラインから OS X アプリケーションを閉じるにはどうすればよいですか?

答え1

Preview.app で AppleScript コマンドを受け入れるようにする

デフォルトでは、AppleScriptingプレビューは必要な辞書がないため機能しません。これを修正するには、ローリの答えはこちらNSAppleScriptEnabledPreview.app の設定について説明します。

Preview.app を終了し、ターミナルを開いて次のように入力します。

sudo defaults write /Applications/Preview.app/Contents/Info NSAppleScriptEnabled -bool true
sudo chmod 644 /Applications/Preview.app/Contents/Info.plist
sudo codesign -f -s - /Applications/Preview.app


アプリケーションからウィンドウを閉じる

1) ウィンドウのインデックスまたはウィンドウの名前

名前付きアプリケーションのウィンドウを閉じるコマンドは次のようになります。

tell application "Preview" to close window 1

…または、名前付きドキュメント ウィンドウを閉じる場合、例foo.jpg:

アプリケーション「プレビュー」に「jpg の

したがって、シェル スクリプトでは次のようになります。

#!/bin/sh
osascript <<EOF
tell application "Preview"
  close (every window whose name is "$1")
end tell
EOF

ここで、スクリプトに渡される最初の引数は、閉じるウィンドウの名前です (例: ) ./quit.sh foo.jpg。ファイルにスペースが含まれている場合は、ファイル名を引用符で囲む必要があることに注意してください (例: ) ./quit.sh "foo bar.jpg"

または、任意のアプリケーションから任意のウィンドウを閉じる場合は、次のようにします。

#!/bin/sh
osascript <<EOF
tell application "$1"
  close (every window whose name is "$2")
end tell
EOF

./quit.sh Preview foo.jpgここでは、たとえばを使用します。

2) ファイル名で

特定のドキュメントに属するウィンドウを閉じたいが、ファイル名を指定したい場合は、別の方法が必要です。これは、複数ページの PDF は として表示できるが、 AppleScript に をfoo.pdf (Page 1 of 42)渡すだけだからです。foo.pdf

ここでは、ウィンドウを反復処理し、ファイル名をスクリプトに渡された引数と比較します。

osascript <<EOF
tell application "Preview"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$1") then
            close window x
        end if
    end repeat
end tell
EOF

これで、 を呼び出すだけで済みます./quit.sh foo.pdf。一般的な方法では、名前付きドキュメント ウィンドウを持つすべてのアプリに対して、次のようになります。

osascript <<EOF
tell application "$1"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$2") then
            close window x
        end if
    end repeat
end tell
EOF


注意: Preview.app の自動終了

Preview.app は、最後のドキュメント ウィンドウが閉じられると自動的に終了するアプリケーションの 1 つです。これは、メモリを節約して「クリーンアップ」するために行われます。この動作を無効にするには、次のコマンドを実行します。

defaults write -g NSDisableAutomaticTermination -bool TRUE

もちろん、元に戻すにはTRUEに変更しますFALSE


スクリプトの代わりに関数を使用する

最後に、スクリプトをシェルで常に使用できる関数に入れることをお勧めします。これを行うには、スクリプトを に追加します~/.bash_profile。このファイルが存在しない場合は作成します。

cw() {
osascript <<EOF
tell application "$1"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$2") then
            close window x
        end if
    end repeat
end tell
EOF
}

bash プロファイルを保存してシェルを再起動すると、cw Preview foo.pdfどこからでも呼び出すことができます。

答え2

slhck による回答は優れていて徹底しているように見えます。3行目のコードを実行すると:

sudo codesign -f -s - /Applications/Preview.app

次のように、起動するたびにプレビューがクラッシュする原因となっているようです。

Application Specific Information:
XPC domain creation failed: The code signature is not valid: The operation couldn’t be completed. (OSStatus error -67061.)

コード署名マニュアルによると、これは-f「既存の署名を置き換えるコード署名」を強制し、-s「指定されたパスのコードに署名する」ことです…この場合-

どうやら、プレビューは誤って署名されており、使用できなくなっています。 :(

関連情報