Problem building command line from code

Started by Joanna Carter, August 24, 2018, 07:17:32 AM

Previous topic - Next topic

Joanna Carter

I am in the process of building a wrapper for ExifTool in Swift.

So far, I have been able to do simple commands for extracting and setting keywords but, when it comes to trying something a bit more adventurous, things are starting to go a bit pear-shaped  :o

I am trying to encapsulate the command for copying a load of files form one directory into a hierarchy of directories, according to the file's DateTimeOriginal tag.

The working command line is:

exiftool -recurse -ext jpg -out . '-Directory<DateTimeOriginal' -d /Users/joannacarter/Pictures/%Y/%m/%d /Volumes/Joanna\ C/DCIM/

My wrapper works with parameterised enums to avoid spelling errors when typing arguments. So I get the following debug output from inspecting the array of Argument enums that will be "stringified" and sent to the external process:

(lldb) po arguments
▿ 5 elements
  - 0 : -recurse
  - 1 : -out .
  ▿ 2 : '-Directory<DateTimeOriginal'
    - directoryFromTag : DateTimeOriginal
  ▿ 3 : -d /Users/joannacarter/Pictures/%Y/%m/%d
    ▿ dateWithUrl : 2 elements
      ▿ formatSpecifiers : 3 elements
        - 0 : %Y
        - 1 : %m
        - 2 : %d
      ▿ url : file:///Users/joannacarter/Pictures/
        - _url : file:///Users/joannacarter/Pictures/
  ▿ 4 : /Volumes/Joanna\ C/DCIM/
    ▿ directory : file:///Volumes/Joanna%5C%20C/DCIM/
      - _url : file:///Volumes/Joanna%5C%20C/DCIM/

This then translates into an array of strings:

(lldb) po executionArguments
▿ 5 elements
  - 0 : "-recurse"
  - 1 : "-out ."
  - 2 : "\'-Directory<DateTimeOriginal\'"
  - 3 : "-d /Users/joannacarter/Pictures/%Y/%m/%d"
  - 4 : "/Volumes/Joanna\\ C/DCIM/"

And, when I concatenate them together, I get:

"-recurse -out . \'-Directory<DateTimeOriginal\' -d /Users/joannacarter/Pictures/%Y/%m/%d /Volumes/Joanna\\ C/DCIM/"

... which is, in turn, concatenated to exiftool So, I send those arguments to the external process but, when I launch it, I get the following errors in the debugger console:


Invalid TAG name: out .
Invalid TAG name: d /Users/joannacarter/Pictures/%Y/%m/%d
Error: File not found - '-Directory<DateTimeOriginal'
Error: File not found - /Volumes/Joanna\ C/DCIM/


I'm going to guess that I'm missing something really stupid here but sometimes it a case of not seeing the wood for the trees.

Joanna

Joanna Carter

OK. In a bid to solve this, I found a message from someone else that talks about having certain parts of the args on different lines in the args file.

This may be a red herring but...

In this line: exiftool -recurse -ext jpg -out . -Directory<DateTimeOriginal -d /Users/joannacarter/Pictures/%Y/%m/%d /Volumes/Joanna\ C/DCIM/

Can someone tell me where one arg ends and another one starts?

The message in question talks about -ext and jpg being on different lines

StarGeek

#2
Every item is a separate argument. 

-recurse
-ext
jpg
-out
.
-Directory<DateTimeOriginal
-d
/Users/joannacarter/Pictures/%Y/%m/%d
/Volumes/Joanna\ C/DCIM/
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Joanna Carter

Now that is interesting.

With Swift/Cocoa, I have a Process object that is set up by passing the executable URL to one property and an array of "arguments" to another.

I take it you missed splitting the two "URLs" on the last line but, do I understand correctly that, even though I would expect two items like -ext (which is an arg) and jpg (which is the parameter to that arg) to belong together, when they are passed to the Process, they need to be separate items in the list?

I'm beginning to feel like Alice in Wonderland - "curiouser and curiouser"  ???

StarGeek

Quote from: Joanna Carter on August 24, 2018, 07:03:28 PM
I take it you missed splitting the two "URLs" on the last line

Yes, my mistake. Corrected

Quotebut, do I understand correctly that, even though I would expect two items like -ext (which is an arg) and jpg (which is the parameter to that arg) to belong together, when they are passed to the Process, they need to be separate items in the list?

It may be a parameter to the -ext, but it is still a separate arg. 

As for the issue with '-Directory<DateTimeOriginal', quotes are probably not necessary as the quotes are there to prevent file redirection and it appears that it is being passed as a complete argument and the quotes are being passed as part of that argument, which is why you there was a Error: File not found error for it.  The quotes are being included.  Similar situation with /Volumes/Joanna\ C/DCIM/.  The backslash is there to escape the space on the command line, but since this isn't the command line, there's no need to escape it.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Joanna Carter

Yeeessssss !!!

Thank you so much for filling that hole in my understanding of creating command lines  ;D

I have now modified my wrapper framework from things like Argument.extension("jpg"), which created one arg "-ext jpg", to Argument.extensionFlag, Argument.extension("jpg"), which creates two args "-ext" and "jpg"

:-* Joanna

philbond87

Joanna,

I realize this is a rather old thread.
Would you mind telling me what you used for the launch.Path to reach exiftool?

My understanding is that shells often have a different environment than the terminal. Using a different programming environment (not Swift) I have to specify the path to exiftool as /usr/local/bin (the standard installation location). What are you using in Swift?

Thanks,
Phil