Waiting until Acrobat closes file
|
|
Thread rating:  |
Tommy Nordgren - 27 May 2006 23:27 GMT My perl script generates pdf files, and opens them with Acrobat. How can I wait until Acrobat closes the file, so I can delete it? ------------------------------------------------------ "Home is not where you are born, but where your heart finds peace" - Tommy Nordgren, "The dying old crone" tommy.nordgren@chello.se
David Cantrell - 28 May 2006 00:34 GMT > My perl script generates pdf files, and opens them with Acrobat. > How can I wait until Acrobat closes the file, so I can delete it? system('acroread', 'myfile.pdf'); unlink('myfile.pdf');
if instead you're doing something like ...
system('open', '/Applications/Acrobat.app');
then you'll need to:
wait around until Acrobat appears in the process table; wait around until that PID disappears;
Check out Mac::Processes on the CPAN.
 Signature David Cantrell | random organic glop and a metric fuckton of electricity
Wow, my first sigquoting! I feel so special now! -- Dan Sugalski
Chris Devers - 28 May 2006 01:47 GMT > if instead you're doing something like ... > [quoted text clipped - 4 lines] > wait around until Acrobat appears in the process table; > wait around until that PID disappears; Really??
In my experience, the `open` command immediately returns control to the controlling process (the shell, or whatever else invoked it (pine etc)) without waiting for the `open`ed application to finish, or for that matter even to finish launching.
If you're going to use acroread, then [a] you have to install it, and [b] you have to view the document in X11. Yuck. Surely that isn't really the best way to approach this, is it? I'd have thought that the `open` command was the perfect answer to this question... system('open', '/Applications/Preview.app');
etc.
 Signature Chris Devers DO NOT LEAVE IT IS NOT REAL
Joel Rees - 28 May 2006 06:53 GMT >> if instead you're doing something like ... >> [quoted text clipped - 19 lines] > > system('open', '/Applications/Preview.app'); Well, I think the orginal problem was waiting until the viewer closed the document to delete the file. So, whichever viewer you use (X11 acrobat reader, Mac OS X acrobat reader, preview app, something else) you're still stuck with the problem of how to avoid deleting a file out from under the viewer.
Except, of course, this is Unix, and we have i-nodes, and the system knows how to hold onto a file until all links are gone, as I recall.
Ergo, just delete it once you know the viewer has it open, IIRC.
David Cantrell - 28 May 2006 18:44 GMT > Except, of course, this is Unix, and we have i-nodes, and the system > knows how to hold onto a file until all links are gone, as I recall. > > Ergo, just delete it once you know the viewer has it open, IIRC. Which is fine, but if you use 'open' to fork off and run Acrobat in parallel with your program, then at the moment system() returns you do *not* know that it has safely grabbed hold of the file. You don't even know that it has when you see Acrobat appear in the process table.
 Signature David Cantrell | http://www.cantrell.org.uk/david
Eye have a spelling chequer / It came with my pea sea It planely marques four my revue / Miss Steaks eye kin knot sea. Eye strike a quay and type a word / And weight for it to say Weather eye am wrong oar write / It shows me strait a weigh.
Joel Rees - 28 May 2006 21:26 GMT >> Except, of course, this is Unix, and we have i-nodes, and the system >> knows how to hold onto a file until all links are gone, as I recall. >> Ergo, just delete it once you know the viewer has it open, IIRC. There is only one way to be sure it is _your_ child process that has opened it. I'm pretty sure it involves looking at the table of open files. However, ...
> Which is fine, but if you use 'open' to fork off and run Acrobat in > parallel with your program, then at the moment system() returns you do > *not* know that it has safely grabbed hold of the file. You don't > even know that it has when you see Acrobat appear in the process > table. since you do need to take the steps to be sure it is your child process that has it open, once you have taken those steps, there is no need to wait around for it to close. IIRC.
Christian Huldt - 28 May 2006 08:15 GMT 28 maj 2006 kl. 02.47 skrev Chris Devers:
>> if instead you're doing something like ... >> [quoted text clipped - 13 lines] > without waiting for the `open`ed application to finish, or for that > matter even to finish launching. which is why processes have to be monitored manually...
I'm quite confident that David meant system('/Applications/Adobe Reader 7.0.7/Adobe Reader 7.0.7.app/ Contents/MacOS/Adobe Reader', 'myfile.pdf'); using acroread as shorthand
This will block as long as the process is running, to just wait while the document is open, I'd probably try monitoring `lsof | grep myfile.pdf`; after system ('open',...
unless you can arrange for Acrobat to quit, which however would cause a lot of time wasted for launching if you will process more than one document...
(I assume the the full Acrobat can be controlled using Mac::Glue, but this does not seem possible for the Reader)
David Cantrell - 28 May 2006 18:41 GMT >> if instead you're doing something like ... >> system('open', '/Applications/Acrobat.app'); [quoted text clipped - 7 lines] > without waiting for the `open`ed application to finish, or for that > matter even to finish launching. Yes, and that is why I said you need to:
wait around until Acrobat appears in the process table
because you can't guarantee that it'll be there when 'open' returns control to your perl program - 'open' will have fork()ed and exited but won't necessarily have exec()ed by then. And that you need to then
wait around until that PID disappears
because, erm, it's running in parallel to your program. Do try to keep up old chap :-)
 Signature David Cantrell | Benevolent Dictator Of The World
When one has bathed in Christ there is no need to bathe a second time -- St. Jerome, on why washing is a vile pagan practice
Wren Ng Thornton - 28 May 2006 23:34 GMT > Really?? > > In my experience, the `open` command immediately > returns control to the controlling process (the shell,
> or whatever else invoked it (pine etc)) without > waiting for the `open`ed application to finish, or for > that matter even to finish launching. Others have gone over briefly why your observations about `open` returning are correct, but why that's actually the root of the problem. The problem isn't that it takes too long to return, it's that it returns too quickly. The issue in general is race conditions.
Because `open` returns so soon you have no idea when the other app will open the file let alone close it. If you delete the file right away it may be missing by the time the app is up and running; if you delete it after it's been opened but before it's been closed, the app may choose to "undelete" it for you by saving it or whatnot.
The only real way around this problem is to wait for the app to close and only then delete the file, and the only way to get that information without race conditions itself is from the OS itself. You'll want the new process to be a child process so you can know definitively that it has completed (and without constantly polling the process table). system() does this, though you'll want to launch the app directly rather than using something like `open` to open it indirectly.
Since terminated processes can't have open files you can be sure that once the child finishes, the file is closed (or at least closed as far as your program is concerned, other processes out there in the universe may muck with your plans to delete it, but you have no control over that).
In short, `open` is an awesome utility that I wish all *nices had, but it's not the right tool for this job.
Live well, ~wren
__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Joseph Alotta - 29 May 2006 06:19 GMT This may not be what you are looking for, but if you were to name the files in a way that uses the date, then you can just delete the old ones the next day.
Joe.
On May 28, 2006, at 5:34 PM, wren ng thornton wrote:
>> Really?? >> [quoted text clipped - 48 lines] > Tired of spam? Yahoo! Mail has the best spam protection around > http://mail.yahoo.com Tommy Nordgren - 10 Jun 2006 23:49 GMT >> My perl script generates pdf files, and opens them with Acrobat. >> How can I wait until Acrobat closes the file, so I can delete it? > > system('acroread', 'myfile.pdf'); > unlink('myfile.pdf'); There is no 'acroread' , at least not with only the reader installed
> if instead you're doing something like ... > [quoted text clipped - 4 lines] > wait around until Acrobat appears in the process table; > wait around until that PID disappears; 1. Acrobat may already be running when told to open a document. 2. I would prefer being able to remove the file as soon as it is closed, keeping the reader running is preferable, since it has long start up time. Will it work to: a) Wait until Acrobat Reader is running b) Sleep long enough to make sure acrobat has opened the file c) Open the file in read/write mode, and wait until a write lock can be aquired d) Then , close and remove the file
> Check out Mac::Processes on the CPAN. ------------------------------------------------------ "Home is not where you are born, but where your heart finds peace" - Tommy Nordgren, "The dying old crone" tommy.nordgren@chello.se
Joel Rees - 11 Jun 2006 00:24 GMT > Will it work to: > a) Wait until Acrobat Reader is running > b) Sleep long enough ... Instead of depending on timing, which will always get messed up when you can least afford it, get a list of the open files from the system.
man lsof
There should be better ways to get the file handle, but you should at least be able to look through the list of open files given by lsof for an instance of your file opened by the process whose id is the acrobat reader you asked to open it.
|
|
|