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:
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.
subprocess.call(['open','-a','Preview',path])
? Works for me.open -nWa Preview $pdf
to cause the command not to return until the spawned Preview process ends (-n is for creating a new instance).