4

I have a Mac VM running Mavericks (10.9.3), and for various reasons I am trying to write a script in Python to automatically transfer a PDF file to the VM and open it in Preview. For anyone who doesn't know, the command <path-to-Preview> <path-to-file> will open the file.

Whenever the script runs, Preview will open, but it will give this error message: Error Message

This is just a sample PDF file, I have tried it with a couple other PDFs as well. This error does not occur when I open the file by double-clicking it. Only when I try to script it. The error also does not occur as long as the file has been opened manually once.

There are a couple other errors as well (paths sanitized).

Error in Terminal

2014-08-22 09:33:49.074 Preview[276:2c0b] PVPDFPageContainer initWithURL:file:///path/The-Apple-Sandbox-BHDC2011-Paper.pdf failed, error = Error Domain=NSCocoaErrorDomain Code=257 "The file “The-Apple-Sandbox-BHDC2011-Paper.pdf” couldn’t be opened because you don’t have permission to view it." UserInfo=0x7fe7504ba220 {NSFilePath=/path/The-Apple-Sandbox-BHDC2011-Paper.pdf, NSUnderlyingError=0x7fe7504ba1f0 "The operation couldn’t be completed. Operation not permitted"}

Error in Console

9:33:49 AM sandboxd: 
([276]) Preview(276) deny file-read-data path/The-Apple-Sandbox-BHDC2011-Paper.pdf

Things I have tried

  • Repairing the disk permissions using disk utility and restarting the VM
  • Changing the permissions of the file to 777 before opening
  • Removing any extra file attributes (like quarantine) with xattr before opening

The result of ls -l@ in the directory shows the file permissions are:

-rwxrwxrwx  1 me  wheel  364378 Aug  7 14:54 The-Apple-Sandbox-BHDC2011-Paper.pdf

The relevant part of my script looks something like this:

import subprocess
import os

path = <absolute path to PDF>
os.chmod(path, 0777)
result = subprocess.call(["xattr", "-c", path]) #result is always 0/success
preview = "/Applications/Preview.app/Contents/MacOS/Preview"
subprocess.call([preview, path])

Edit: As per aglasser's comment, subprocess.call(['open','-a','Preview',path]) does work where my command will not.

However, I need to be able to get the pid of the Preview process that is started (my script has been simplified down for this, so it wasn't obvious) and I don't see any way to do that with open, especially with multiple Preview process potentially running. I may need a separate question for that.

More Info for Anyone Else with This Problem
The root cause of this issue appears to be Apple's application sandbox. Apparently attempting to script it in this way doesn't work with the sandbox, but "open" goes through the proper channels to satisfy whatever requirements the sandbox has.

7
  • What about subprocess.call(['open','-a','Preview',path])? Works for me.
    – aglasser
    Aug 22, 2014 at 16:40
  • Hmm, yes, that does work. I wonder what that does differently. However, I need to track the pid of the different Preview processes, and I don't see any way to do that with open. Maybe I need another question for that...
    – Testing
    Aug 22, 2014 at 16:50
  • @Testing: If the reason you need the pid is to know when Preview has quit, you can use open -nWa Preview $pdf to cause the command not to return until the spawned Preview process ends (-n is for creating a new instance).
    – 0942v8653
    Aug 22, 2014 at 19:06
  • Unfortunately I need the pid for more than that - I send Preview a couple of commands, I'm not really all that interested in when it exits. I've been doing a lot of Googling on open and getting pids, but all I'm getting is that it's really not possible. So "open" will not work in my specific case. If you want to post your command as an answer though, @aglasser, I'll accept it, since it does answer the original question even if I can't use it.
    – Testing
    Aug 22, 2014 at 19:42
  • fwiw I'm having a similar problem, but not from python: I have a bunch of jpg files created by matplotlib and rsync'd from an ubuntu server to my mac. Most of them can be opened in Preview ok, but there is a subset that can't, with the error above. Permissions are all identical, so Preview is lying about permissions...
    – drevicko
    Dec 1, 2017 at 11:30

2 Answers 2

1

I have tested this a bit in my free time today, and it seems that subprocess.call(['open','-a','Preview',path]) is your best option for opening PDFs in Preview from Python.

I'm still not sure why using the absolute path to Preview doesn't work, though.

I am trying to find a way to get a process PID based on its window title in AppleScript. For example, if you were to open a document named "Test.png" in Preview with that command, it would spawn a Preview window with the window title "Test". I am hoping there is a way to get the PID of this process using the window title, but I'm not sure yet.

1
  • Thanks, let me know if you find anything promising on the PID-via-window-title approach.
    – Testing
    Aug 22, 2014 at 20:29
0

It seems Preview sometimes gets confused with pemissions. A similar problem was solved by this answer by simply quitting preview.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .