Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Running an external GUI program

by mdrisser (Acolyte)
on Feb 01, 2007 at 00:22 UTC ( #597669=perlquestion: print w/replies, xml ) Need Help??

mdrisser has asked for the wisdom of the Perl Monks concerning the following question:

I have a situation where I need to run an external program.

Basically I guess what I'm doing is a kind of batch processing. I have a bunch of PDFs that I need to compress on MacOSX. I can call the program I need to run by passing it a single filename with system, but then my Perl program goes off into lala land waiting for the external program to return, but since its GUI it just sits there waiting for another file and never returning.

Is there a way to force the GUI to exit after it has processed the file I sent it? Or is there a better way to do what I'm trying to do? I've tried the whole filehandle pipe deal as shown in the Perl Cookbook, but that really doesn't do what I need to do. Since I'm not really writing to the program, just passing it another filename to work with.

Any help here will be greatly appreciated.

Replies are listed 'Best First'.
Re: Running an external GUI program
by graff (Chancellor) on Feb 01, 2007 at 02:22 UTC
    What sort of compression are you talking about, and why does it need to be done with a GUI-based tool? If you can be flexible about the style of compression you want to do, you could just do something on the shell command-line:
    # simple case: compress all pdf files in current directory: gzip *.pdf # recursive-search case: compress all files under some path: find some/path -name '*.pdf' -print0 | xargs -0 gzip
    Or, if you look up the help/manual on the command that you are currently using (whatever that is), you might find out whether it accepts a "batch-mode" or "non-interactive" option as a command-line flag.

    (The worst thing about GUI apps that perform basic operations is that they are not suitable for doing batch processing.)

Re: Running an external GUI program
by liverpole (Monsignor) on Feb 01, 2007 at 00:41 UTC
    Hi mdrisser,

    It depends.  If, by "external", you mean "on a remote machine", it may be difficult or impossible.  If, though, you just mean separate from your Perl program (as I think you do), there are a number of possibilities.

    One is, of course, kill.  It's a bit of a strong measure, though it may be your only recourse.  Update:  Now that I rethink this, kill of course won't work, since your process is remote.  I'm thinking more of a Linux kill; I don't know what the corresponding command is for that on a Mac system, but there must be something.

    Alternatively, perhaps the GUI has a non-interactive mode where you can pass it arguments, have it do its work, and then exit?  That's what I do with DVD-burning (which I do at my job); I have a Perl script running on my Windows machine which responds to commands from a Linux box, over a socket.  Then it runs the DVD-burning software in "batch" mode (ie. non-interactively), so that when it's done, it's done (and the DVD-burning software simply exits).


      Hi liverpole,

      Thanks for the response.

      By external I meant external to Perl, the GUI resides on the same machine as the Perl code so that's not an issue.

      I thought about using kill, but I need someway to make sure it has finished processing the file before I kill it.

Re: Running an external GUI program
by syphilis (Bishop) on Feb 01, 2007 at 03:10 UTC
    I have a bunch of PDFs that I need to compress

    What sort of compression ? Both gzip and bzip2 compression can be done using perl without the need to shell out at all (by using Compress-Raw-Zlib and Compress-Raw-Bzip2, and other modules that offer higher level access).

Re: Running an external GUI program
by wjw (Priest) on Feb 01, 2007 at 01:07 UTC
    was thinking about this a bit. Only things I could come up with was to check to see if there are command line switches that you can hand off to the GUI program that will give you the behaviour you want. I am guessing that there probably is not. (I think a previous poster mentioned this, so nothing new here)

    The other thought I had was to keep track of the process id AND the lock state on the file that you hand to the GUI program. My thinking is that if the GUI program is modifying the PDF file you have handed it, it is probably locking it until it is done processing. If that is the case, you might be able to issue a kill to the pid after the lock is removed. Am not sure of how OSX keeps track of processes, or how you kill them off.

    Good luck! :-)

    ...the majority is always wrong, and always the last to know about it...

Re: Running an external GUI program
by herveus (Parson) on Feb 01, 2007 at 12:36 UTC

    Have you looked into using AppleScript to control the application? I think you should be able to end your script with a quit command.

    There are a number of Mac:: modules on CPAN that may help with this, but I have not really played with them.

Re: Running an external GUI program
by Moron (Curate) on Feb 01, 2007 at 12:36 UTC
    There is about a 99% chance that syphilis's answer covers it. But for the record, if the program spawned by the GUI is not so well supported by Perl as to have a module for it, then Unix::PID might be useful, e.g.
    use Unix::PID; my $ps = new Unix::PID -> new(); # wait for completion of GUI's subprocess $ps -> wait_for_pidsof("name of program spawned by GUI"); # kill the GUI process $ps -> kill( $ps -> get_pidof("name of GUI program") );
    Mac OSX conforms sufficiently to Unix for the purposes of this module, although the module documentation doesn't appear to give a list of supported environments.

    Update: in a multi-user environment parents and children would have to be user-id'd and matched up before doing the wait then kill.


    Free your mind

Re: Running an external GUI program
by chargrill (Parson) on Feb 01, 2007 at 16:57 UTC

    Simplest solution I can think of is to have perl run an applescript. You'll have to dig around in the Script to find out how to script your application properly. Once you have a working applescript, you can just plug it into the likes of this:

    use Mac::AppleScript qw(RunAppleScript); ... sub run_script { my $script; my $msg = shift; ($script = <<" EOS") =~ s/^\s+//gm; tell application "PDFCompressor" ... # more applescript here end tell EOS RunAppleScript( $script ) or die "couldn't run applescript - $!"; }

    s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)
Re: Running an external GUI program
by spatterson (Pilgrim) on Feb 01, 2007 at 15:31 UTC
    There's a lot of perl compressors (gzip, bzip2 et al) on CPAN Compress which you could use instead of a GUI program

    just another cpan module author
Re: Running an external GUI program
by rzer10 (Acolyte) on Feb 01, 2007 at 16:38 UTC
    On a UNIX system you can run the remote process in the background by appending "&" to the command. For example, if I have a utility called "/my/bin/a.out" and I want to run it on a file called "xxx" I do this: system '/my/bin/a.out xxx &'. Not too familiar with MacOSX but I believe it is UNIX based is it not? On my PC, I use the Win32::Process module. It also allows you to run a process in the background. Perhaps there is a MacOS equivalent.
Re: Running an external GUI program
by Anonymous Monk on Feb 01, 2007 at 21:41 UTC

    Thanks for all the great ideas.

    As far as compression goes, I can't use bzip, gzip, etc. because the PDFs need to be viewable on the web. There are no command line switches that I have been able to find unfortunately, so that's out.

    I'm not sure how to check the file lock, as has been suggested, but I will look in to that. Since OSX is built on a BSD kernel, it should be pretty straight forward to do.

    The AppleScript option seems to be a rather promising alternative to calling the app from the command line.

    I'll have to let you know what the results are.

      The compression used by gzip is compatable with one of the compression encodings on the web. Unless you are talking about optimizing the PDF for web use, which is an entirely different can-o-worms.


      What compression tool are you using?

      Even if that tool doesn't have a batch/command-line way to run it, there are probably other equivalent tools out there. For example, you might look at It is admittedly not in perl (it is in the other popular four-letter cross-platform language), but it is a free tool that shrinks PDF files but keeps them as PDF format (i.e. it does the compression internal to the PDF format so they are directly readable by PDF viewers). It is command-line based. There is a perl script up on that uses the ghostscript library to create smaller PDF files -- that particular script is from a package called "Scribus", but it could serve as a starting point).

      Best of luck.

        Another tool to consider: pdftk

        From the blurb ...

        If PDF is electronic paper, then pdftk is an electronic staple-remover, hole-punch, binder, secret-decoder-ring, and X-Ray-glasses. Pdftk is a command-line tool for doing everyday things with PDF documents. Keep one in the top drawer of your desktop and use it to:

        * Merge PDF Documents
        * Split PDF Pages into a New Document
        * Decrypt Input as Necessary (Password Required)
        * Encrypt Output as Desired
        * Fill PDF Forms with FDF Data and/or Flatten Forms
        * Apply a Background Watermark
        * Report on PDF Metrics such as Metadata, Bookmarks, and Page Labels
        * Update PDF Metadata
        * Attach Files to PDF Pages or the PDF Document
        * Unpack PDF Attachments
        * Burst a PDF Document into Single Pages
        * Uncompress and Re-Compress Page Streams
        * Repair Corrupted PDF (Where Possible)

        Pdftk allows you to manipulate PDF easily and freely. It does not require Acrobat, and it runs on Windows, Linux, Mac OS X, FreeBSD and Solaris.

        Pdftk is free software (GPL).

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://597669]
Approved by astaines
Front-paged by andyford
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2021-10-16 03:58 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (69 votes). Check out past polls.