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

Hi,

Iam new to Perl on Windows and hence landed up here. I need to run du command in the background within the perl script on windows which takes some 5mins. Also i need to capture the output of this command to a file. I searched many forums and could understand Proc::Background suits the best. But iam not sure how to capture the output. Below is the thing i tried.

use Proc::Background; my $cmd="du(qw//usr/bin//); my $proc=Proc::Background->new($cmd); my $alive=$proc->alive; my $pid=$proc->pid; print "pid is $pid\n";

Now iam struck how to capture output of the du cmd.Please suggest.

Replies are listed 'Best First'.
Re: running a cmd in background and capturing the output
by Corion (Patriarch) on Oct 09, 2013 at 10:27 UTC

    If you want to capture the output of a program, backticks are the easiest approach (Quote Like Operators. If you want to read the program output before it has finished running, look at the pipe-form of open.

    If for some reason you are tied to using Proc::Background, launch the other process and redirect its output to a file. In your main program, read from that file.

Re: running a cmd in background and capturing the output
by dasgar (Priest) on Oct 09, 2013 at 12:51 UTC
    Also i need to capture the output of this command to a file.

    If you just need the command output in a file and not using it elsewhere in your script, you could just pipe the output of the command to the file named "file.txt". For example, your sample code appears to be calling the command du /usr/bin. You could modify it to be du /usr/bin > file.txt to pipe the STDOUT to a file.

    If you do need the output in other parts of your script, then I personally would do this using threads. To go that route, I would probably create a subroutine that expects a directory as input and returns the output of the running the du command on that directory. Then you call that routine in a thread.

    Just tossing out a few other suggestions.

Re: running a cmd in background and capturing the output
by Anonymous Monk on Oct 09, 2013 at 12:14 UTC

    Why can you not do similar to the following ...

    perl -e "print qx[du /dir/path]" &
    ... ?

    use AnyEvent::Fork as a faster fork+exec seems to provide enough code for OP (could be overkill).

    Not directly related to OP ...

    I was thinking of IPC::Run, open3, etc. when I read OP but that by itself won't run in background (well, short of /some/program &).

    That Proc::Background sure is nice for it takes care of fork, child pid, and the related bits. But of course does not have the facility to get to the output.

    Then there is No::Worries::Proc which can provide command output. Also, installs default signal handlers that I do appreciate. I, however, cannot get over the namespace of No::Worries!? There are bound to be issues despite the gratuitous misuse of the namespace by virtue of being the "First!".

    I wonder if P::Background could be modified to capture the output in minimum of code (unlike N::W::Proc), with addition of signal handlers ... though having read AE::Fork, I am leaning toward it.

Re: running a cmd in background and capturing the output
by Laurent_R (Canon) on Oct 09, 2013 at 18:50 UTC

    If you need the output of the command in your program (you presumably do), then you have to wait for this command to complete and using back ticks is probably the best solution, even if it is arguable that this is not exactly background.

      Thanks to All for the suggestions, but i tried this way and its working good.

      my $myproc = Proc::Simple->new(); $myproc->redirect_output ("/outcome1.txt"); $myproc->start(\&disk_use,"/usr/bin"); my $running = $myproc->poll(); ##to chk if process is still running. my $pid= $myproc->pid; my $bk_id1=$pid; sub disk_use { my $path=shift; my $total_usage=du("$path"); print "total disk uasge is $total_usage\n"; }

      Its working:)