Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: multi-command sytem call

by etcshadow (Priest)
on Aug 25, 2004 at 03:11 UTC ( [id://385569]=note: print w/replies, xml ) Need Help??


in reply to multi-command sytem call

When you run a process in the background via the shell (with the &), the return value is always zero. From shell (bash) docs:
If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0.
What you can do, though, is do something with the return value and then check it later... maybe create a file:
# clean up if the temp files were already there unlink $_ or die "unlink $_: $!\n" for grep {-e $_} "/tmp/a$$", "/tmp/ +b$$"; system("(perl $rpla && touch /tmp/a$$) & (perl $rplb && touch /tmp/b$$ +)"); $rc = -e "/tmp/a$$" && -e "/tmp/b$$"; # cleanup temp files unlink $_ or die "unlink $_: $!\n" for grep {-e $_} "/tmp/a$$", "/tmp/ +b$$";
There are other ways to do this, too... depending on whether you actually *wanted* the output of $rpla and $rplb to go to your terminal, you could do this without temp files at all:
my $output = `(perl $rpla >/dev/null 2>&1 && echo a) & (perl $rplb >/d +ev/null 2>&1 && echo b)`; my $success = $output =~ /a/ && $output =~ /b/;
Anyway, these all rely on the ability of the shell to fork off not just a single command, but a whole command list expression (and then you chain together the command whose status you want to check with another command that is conditional on the status of the first, and has side-effect that you can verify later).
------------ :Wq Not an editor command: Wq

Replies are listed 'Best First'.
Re^2: multi-command sytem call
by diotalevi (Canon) on Aug 25, 2004 at 03:55 UTC
    When you run a process in the background via the shell (with the &), the return value is always zero.

    Not so!

    system, exec, and fork can all fail and depending on the function, return a non-zero value if the system cannot fork at the time (say, if there is a runaway process running that has forked too many times). Or actually, on failure fork returns undef, exec returns false, and system returns whatever the secondary process returned. Normal programs return 0 on success but are expected to return non-zero values on failure. So system is perfectly capable of returning non-zero values. When that happens, something wrong has happened in the program that system was running.

    The return code of the program is in $? >> 8 so check that when it fails.

      Well, I was talking about the return code in the shell (since this was really more of a shell question than a perl question) and quoting the shell documentation. The OP was talking about the return values of the backgrounded processes, which are ignored in terms of computing the exit code of the shell process, and that's all I meant. I probably should have been more precise, though.
      ------------ :Wq Not an editor command: Wq
Re^2: multi-command sytem call
by Elijah (Hermit) on Aug 25, 2004 at 04:20 UTC
    The main difference between system() and exec() is that exec() forks the child and does not wait for a return, meaning it does not wait until the child process does it's thing and then continue. The system() command does just that, When you use system() the call waits for the child process to do it's thing and then reports the exit status of the child. If the child fails it reports whatever failed status the child exited with.

    Hell it could even be a status of zero. You could explicitly assign an exit(0) to an error exit if you so choose. Take the following code fore example:

    #!/usr/bin/perl -w use strict; my $var = 1; if ($var == 1) { print "Hello World!\n"; }else{ exit(0); }
    In this scenario if the program fails to do what it is suppose to do it will exit with a status of 0. Now this script did not fail to run but if you changed the value of $var it would failed to do what it was suppose to do.

    exec() does not return the exit status of the child because , as already explianed, it does not wait for this status report. Instead it returns the status of the forking process itself. If it was able to fork the process into the background it returns a successfull status, if it does not it returns an error status.


    www.perlskripts.com
      exec does not fork, it overwrites the current process. It doesn't return, unless something goes wrong, because there's nothing to return to, nor record that it should even try.

      --
      I'm not belgian but I play one on TV.

        I am sorry, yes you are right. Maybe "fork" was a bad word to use here. By it's very nature a forked process runs but the parent process continues to run also. The exec() function does overwrite the current process and is apparent in some simple code such as the following:
        #!/usr/bin/perl -w use strict; my $results = exec("lt", "-al", "."); print <<END; ########################### \$results \= $results ########################### END
        In the above example you will actually see the printed statement appear on the screen following an error message saying that the command "lt" does not exist. When the command or target program does not exist, or the call fails for any other reson is the only time you will get a "return" from exec().
        #!/usr/bin/perl -w use strict; my $results = exec("ls", "-al", "."); print <<END; ########################### \$results \= $results ########################### END
        Now this code will perform the list (ls) command on a *nix system feeding it "-al" as command line arguiments and "." (current dir) as the target to list. That is all the will appear on the screen and the following print statement will never be executed because the exec() function was successfull and overwrote this current process.

        Sorry for any confusion.


        www.perlskripts.com

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://385569]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-04-19 09:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found