calling ARG file from within ARG file (and Error renaming temporary file...)

Started by Mac2, August 11, 2011, 08:48:10 AM

Previous topic - Next topic

Mac2

I produce ARGS files from my app and run these with exiftool.exe under Windows.
I use exiftool.exe with the stay_open option for faster processing. These files look like this (tons of options and switches removed)

-overwrite_original
XMP:subject += ...
IPTC:caption-abstract = ...
...
c:\image.jpg
-execute


When I have finished writing the data and I have updated IPTC or EXIF tags, I want to run the "iptc2xmp.args" and "exif2xmp.args" files provided by Phil to synchronize the changes into XMP.

Currently I do this in separate calls to exiftool, after the original data has been written:

-overwrite_original
-@ iptc2xmp.args
-execute
c:\image.jpg
-overwrite_original
-@ exif2xmp.args
c:\image.jpg
-execute


This works well.

However, during my tests I let other applications run, e.g. Adobe Bridge or LR. These applications monitor the file system and re-read files when they change. If I modify files with exiftool in a folder monitored by the other application, problems may happen.

Sometimes Bridge/LR grab and lock the updated image file immediately after the first call to exiftool. Then exiftool fails to run the args files with the "Error renaming temporary file" because the original image file is currently locked. The same effect shows up with certain on-access virus checkers which also temporarily lock files. Especially under load.

These locks are usually short-lived and held only a second or two.

I'm not sure if exiftool has a "retry/wait" logic when it tries to update/rename a file in case the file is locked.
(Optionally) retrying a couple of times, with short 500ms sleep()s, would most likely solve this problem under Windows. I have seen a number of related error reports on the web so this may help many users.

Or (preferred)

Is it possible to call the iptc2xmp.args etc. from within the orginal args file? This would make exiftool process everything in one step and the image file has to be opened/written/closed only once. No chance for other apps or services to step in and lock the file.
I tried but I seems I cannot get the syntax right.

Phil Harvey

The retry option is something I would have to think about.  I don't like adding extra options (to specify a timeout), but I don't want exiftool to hang unnecessarily waiting for another application to close the file (so I can't just set a long timeout by default).

This is a real security bug in Windows that doesn't exist in other systems, and makes it really easy execute a denial-of-service attack on a Windows system.  I wish they would just fix this.

But recursively loading .args files should be easy.  Just do this from your original .args file:

-@
iptc2xmp.args
-execute


- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mac2

Hi, Phil

not sure how they can solve this. An application must have a way to lock a file in order to prevent other applications from writing to it while it is reading/writing. And such locks can be used for DOS attacks for sure. But I guess UNIX/Linux also has a way to lock files which can be abused in the same way.

I tried your suggestion but I get "No writable tags found" when I structure my file as

-overwrite_original
-XMP:description:some text here
...
-@ #(1)
c:\exiftool\xmp2iptc.args #(2)
c:\image.jpg
-execute

When I leave out (1) and (2) it works. When I change this to

-overwrite_original
-XMP:description:some text here
-execute
-@
c:\exiftool\xmp2iptc.args
c:\image.jpg
-execute

it works. But then I again force ExifTool to open/write/move the output file twice.
I don't get it where to put the argument file line so exiftool understands what I want to do.

Phil Harvey

Quote from: Mac2 on August 11, 2011, 03:12:56 PM
I guess UNIX/Linux also has a way to lock files which can be abused in the same way.

No.  As far as I know this can't be done in Mac/Linux.  Any number of applications can write simultaneously to a file.  In fact, another application can delete the file while it is being written and it doesn't cause problems.

Quote
it works. But then I again force ExifTool to open/write/move the output file twice.
I don't get it where to put the argument file line so exiftool understands what I want to do.

Right.  I understand now.  To do this your way does require writing the output file twice.  But you can do it in a single pass by adding the assignments for the equivalent IPTC tag(s):

-overwrite_original
-tagsfromfile
c:\image.jpg
-@
c:\exiftool\xmp2iptc.args
c:\image.jpg
-XMP:description=some text here
-IPTC:Caption-Abstract=same text here
...
-execute


This will copy the existing XMP to IPTC, then afterwards you write your changes to both XMP and IPTC to keep them synchronized.

The only trick here is that I added a -tagsFromFile option with a constant filename (ie. not "@").  This must be done or else the tags would be copied after assigning your new values (see note 4 in the -tagsFromFile documentation).

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mac2

Hi, Phil

sorry for the confusion. I was unable to describe my intention properly. Let me try again:

My user updates the XMP-dc:title field in the UI of my application. My application then needs to do two things:

1. Update the XMP field in the file
2. Synchronize this to classic (IIM) IPTC

What I do (and what works) is:

-overwrite_original
-XMP-dc:title=New Title
c:\image.jpg
-execute

-@
c:\exiftool\xmp2iptc.args
c:\image.jpg
-execute

These two steps take care that the XMP-dc:title tag is set with the new data. The args file supplied by you copies this information into the IPTC:ObjectName tag, according to the IPTC spec.

I do not want to duplicate the XMP->IPTC synchronize logic in my application (Like you suggested on your reply).
It is much safer to leave this under the control of ExifTool and the args files you supply for that purpose. If you change something in these files to incorporate changes, my app will automatically do it "right", too.

I need a way to perform both tasks (and optionally also XMP2EXIF, XMP2GPS and XMP2PDF as well) in one step, with one -execute. Is this possible?

I could not get it working although I've read the exiftool.exe documentation a number of times. And I run into this locking problem frequently when I update files in my app in a folder which is open or monitored by Bridge or Lightroom.

Phil Harvey

My previous response indicates the solution I would suggest.  You do not have to duplicate the full XMP->IPTC synchronization logic, however you do have to update the corresponding IPTC tag when changing any XMP tag.

This is the only way I can see to do this in a single step.  Otherwise you need to run 2 commands.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mac2

Ah, OK. That's good to know. No solution for this one, then.

Since my users can change any XMP field (and the actual write can take place days later), I would have to duplicate basically all of what you do in the args file.  With all the chances for errors, incompatibilities or just missing when you change something. No good. Better to keep ExifTool in as much control as possible for overall better metadata quality and interoperability.

I think I will just split the two parts into separate runs. This way I can react on errors by just trying to re-run the "args file step" a couple of times, with a short delay. Combined with the cool stay_open feature the performance hit caused by the split should be minimal.