1

I have an expression like

xattr -p com.apple.metadata:_kMDItemUserTags '/Users/Shared/MeinDesktop/fasttemp/Fotos noch einzusortieren/_ORG/Foto.jpg' | xxd -r -p | plutil -convert json - -o -

I want to execute it in my app. So I tried

func readLabels(_ filePath : String) -> String {
    return shell(launchPath: "/usr/bin/xattr", arguments: ["-p", "com.apple.metadata:_kMDItemUserTags", filePath, " | xxd -r -p | plutil -convert json - -o -" ] )
} 

with my helping function to execute a command as:

func shell(launchPath: String, arguments: [String]) -> String
{
    let task = Process()
    task.launchPath = launchPath
    task.arguments  = arguments
    let pipe = Pipe()
    task.standardOutput = pipe
    task.standardError = pipe   

    do {
        try task.run()
    } catch let error as NSError {
        print(error.localizedDescription)
        return ""
    }

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output: String = String(data: data, encoding: .utf8) ?? ""
    return output
}

This works nice with the first parts of arguments until the pipe symbol. With additional params the error is:

xattr: No such file:  | xxd -r -p | plutil -convert json - -o -

What do I need to do, to make this an entire statement to be executed? I don't want to create a command file, execute it, and then delete it again. It should work as all "normal" commands and deliver an return text from std io, which will be taken by my shell function.

I'm using Xcode 12.4 and macOS 11.2.

Magoo
  • 77,302
  • 8
  • 62
  • 84
Peter Silie
  • 825
  • 1
  • 11
  • 16
  • 1
    Note that you can read extended attributes programmatically, without invoking external programs. See https://stackoverflow.com/q/38343186/1187415. – Martin R Feb 10 '21 at 13:17
  • 1
    That's how: https://stackoverflow.com/a/16650638/1801544 I could convert both pipe, but I had hard time with `plutil -convert json - -o -`, I managed to do it manually in Swift, with `PropertyListSerialization` and `JSONSerialization`. – Larme Feb 10 '21 at 13:18
  • 1
    Following Martin R comment, another approach maybe more explicit on how it's done: https://stackoverflow.com/questions/61778159/swift-how-to-get-an-image-where-from-metadata-field/61779360#61779360 – Larme Feb 10 '21 at 13:30
  • That helped a lot. I will use "let list = try fileURL.listExtendedAttributes() ..." which leads me to the number for labelcolors I searched for. Thanks a lot! – Peter Silie Feb 10 '21 at 15:42
  • What is the opposite of: let data = try fileURL.extendedAttribute(forName: attr) let colorList = try PropertyListDecoder().decode([String].self, from: data) ? PropertyListEncoder().encode(?) – Peter Silie Feb 10 '21 at 18:23

0 Answers0