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

man perlfunc tells me (about the system command):

"Does exactly the same thing as "exec LIST", except that a fork is done first, and the parent process waits for the child process to complete."

I recently wrote a perl program:

#!/usr/bin/perl -w use strict; [set up some stuff] foreach my $val (@vals) { [set up some more stuff] system "/usr/bin/mplayer -arg1 -arg2 $file"; }
I expected these to get executed sequentially. Instead, the program started, let's just say "a lot," of these simultaneously, leading to a significant disaster.

I eventually got around this by slamming a sleep statement in the loop, but I want to know what I missed, or basically why it didn't behave as I expected (allowing mplayer to finish executing before continuing).

Replies are listed 'Best First'.
Re: The system command and waiting for the child process to finish
by betterworld (Curate) on Sep 29, 2008 at 11:38 UTC

    If $file contains "&" or other funny characters, you should use the several-arguments way of calling system. Otherwise "&" will instruct the shell to start mplayer in the background, which would explain your problem.

    system('mplayer', '-arg1', '-arg2', $file) and die "could not run mpla +yer";

    I prefer this form unless I really need the shell's functionality.

Re: The system command and waiting for the child process to finish
by Corion (Patriarch) on Sep 29, 2008 at 10:41 UTC

    Most likely it's mplayer itself that doesn't wait. If you take a small test program like

    perl -e 'sleep 5; echo $$'

    then likely the whole setup works.

Re: The system command and waiting for the child process to finish
by JavaFan (Canon) on Sep 29, 2008 at 11:04 UTC
    It could happen if mplayer detaches itself from the parent process. But the version of mplayer I have doesn't do so, and a brief skim through its manual page doesn't show an option.

    Furthermore, I can't reproduce your problem; when I do call mplayer from a Perl program using system, the program waits for mplayer to finish before continuing.

    You don't have a & in your real code, do you?

Re: The system command and waiting for the child process to finish
by Fletch (Bishop) on Sep 29, 2008 at 15:22 UTC

    Ampersands and accidental backgrounding aside, it's also possible that system encountered a problem but since you have no error checking on the call it's blithely continuing on to the next iteration immediately with no indication a failure occured.

    $ perl -le 'for (0..3) { system( "Idonotexist $_" ) }' $ perl -le 'for (0..3) { system( "Idonotexist $_" ) == 0 or warn "syst +em problem (exit $?): $!\n" }' system problem (exit -1): No such file or directory system problem (exit -1): No such file or directory system problem (exit -1): No such file or directory system problem (exit -1): No such file or directory $

    Update: Not to say that's what happened here since as you say you did see a lot of processes running; just that in general it pays to take the extra 15 seconds and put the error handling in place.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.