Different results from xattr and mdls

I want to edit the content creator attribute in a PDF file. This is easily done using Automator using the "Set PDF Metadata" action, but want to do it as part of a shell script. I think I need xattr to do this, but when I tried to edit the field, it doesn't work. The value edited is different than is reported by the mdls command (same field set by Automator).


xattr -p com.apple.metadata:kMDItemCreator test.pdf 
xattr: test.pdf: No such xattr: com.apple.metadata:kMDItemCreator


xattr -w com.apple.metadata:kMDItemCreator '"some value"' test.pdf 


xattr -p com.apple.metadata:kMDItemCreator test.pdf 
"some value"


mdls -n kMDItemCreator test.pdf 
kMDItemCreator = "ScanSnap Manager #iX500 (W)"

Why do the mdls and xattr commands given different results for the same metadata item and how do I write over the KMDItemCreator information given by the mdls command? Automator does this easily so I would think it would be possible to edit the same information in the shell? Thanks for the help!

MacBook Pro (Retina, Mid 2012), macOS Sierra (10.12.5)

Posted on Jun 30, 2017 3:30 PM

Reply
3 replies

Jun 30, 2017 5:44 PM in response to G-Force

What you want to change is internal to the PDF, and cannot be accessed by xattr, or mdls. The following Python solution uses the PyObjC bridge to open the PDF, and write a new creator string into it. This is a command-line solution, where the input and output PDF can have the same name, or different:


pdf_creator.py ~/Desktop/in.pdf ~/Desktop/out.pdf "revised creator string"


The appropriate kMDItemCreator string will update in mdls. Requires System installed Python for ScriptingBridge support.

#!/usr/bin/python # coding: utf-8 # pdf_creator.py - change PDF creator string # VikingOSX, 2017-06-30, Apple Support Communities from Foundation import NSURL, NSMutableDictionary from Quartz import PDFDocument, PDFDocumentCreatorAttribute import os import sys def main(): if len(sys.argv) != 4: print("Usage: {} in.pdf out.pdf \"creator string\"".format(__file__)) sys.exit(1) in_PDF = os.path.expanduser(sys.argv[1]) out_PDF = os.path.expanduser(sys.argv[2]) creator_str = sys.argv[3] fn = os.path.expanduser(in_PDF) url = NSURL.fileURLWithPath_(fn) pdfdoc = PDFDocument.alloc().initWithURL_(url) attrs = (NSMutableDictionary.alloc() .initWithDictionary_(pdfdoc.documentAttributes())) attrs[PDFDocumentCreatorAttribute] = creator_str pdfdoc.setDocumentAttributes_(attrs) pdfdoc.writeToFile_(out_PDF) if __name__ == "__main__": sys.exit(main())

Jun 30, 2017 6:11 PM in response to VikingOSX

Thanks that's great. I'm glad I didn't spend any more time trying to get xattr to work.


If I want to use this python script with an apple script and have it work on the selected files in the finder, how would I accomplish that? The script below did not work for me. Thanks!


-- Get the finder selection to pass to the repeat below
tell application "Finder"
set finderSelectionList to selection as alias list
end tell

-- Change the content creator of the selected files
repeat with theFile in finderSelectionList
    tell application "Finder"
        set a to quoted form of POSIX path of theFile
    do shell script "python ~/Desktop/PDF-creator.py" & a a "new creator string"
    end tell
end repeat

Jul 1, 2017 4:39 PM in response to G-Force

If your python script begins with #!/usr/bin/python, then you do not need to explicitly invoke python in the do shell script. The external Python script does need to be executable: chmod +x python_creator.pdf. Get in the habit of using the underscore with filenames in the shell, as '-' and space have special meaning to Bash.


Both of the script approaches will change the creator attribute to your creator_string. The second version is very sensitive to correct syntax spacing, and escaping any characters (e.g. double-quotes, or '\' characters) that AppleScript will eat, and break the code. Both of the following scripts were tested on El Capitan 10.11.6 with the system Python.


property creator_string : "My creator revision"


tell application "Finder"

if not (get selection) = {} then

set finderSelectionList to (selection as alias list)

else

display alert "Nothing selected in the Finder." giving up after 10

return

end if

end tell

repeat with theFile in finderSelectionList

set a to (POSIX path of theFile)'s quoted form

set args to a & space & a & space & creator_string's quoted form

do shell script "~/Desktop/PDF_creator.py " & args

end repeat

return


property creator_string : "My creator revision" tell application "Finder" if not (get selection) = {} then set finderSelectionList to (selection as alias list) end if end tell repeat with theFile in finderSelectionList set a to (POSIX path of theFile)'s quoted form set args to a & space & a & space & creator_string's quoted form change_pdf_creator(args) end repeat return on change_pdf_creator(theArgs) return do shell script "python <<'EOF' - " & theArgs & " #!/usr/bin/python # coding: utf-8 from Foundation import NSURL, NSMutableDictionary from Quartz import PDFDocument, PDFDocumentCreatorAttribute import os import sys def main(): if len(sys.argv) != 4: sys.exit(1) in_PDF = os.path.expanduser(sys.argv[1]) out_PDF = os.path.expanduser(sys.argv[2]) creator_str = sys.argv[3] url = NSURL.fileURLWithPath_(in_PDF) pdfdoc = PDFDocument.alloc().initWithURL_(url) attrs = NSMutableDictionary.alloc().initWithDictionary_(pdfdoc.documentAttributes()) attrs[PDFDocumentCreatorAttribute] = creator_str pdfdoc.setDocumentAttributes_(attrs) pdfdoc.writeToFile_(out_PDF) if __name__ == '__main__': sys.exit(main()) EOF" end change_pdf_creator

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Different results from xattr and mdls

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.