in reply to How to hide system(); output.

If you were using anything but a windows system, you could just form the command line like this:
$command = "(do this && do that) >/dev/null 2>&1";
Maybe the default "cmd.exe" (or whatever gets used on windows to run commands via the system() call) provides some equivalent sort of idiom, if you know how to look that up... (or maybe you can set things up so that your "do this, and do that" stuff gets run via a bash.exe shell, so you can at least redirect output to some file that you can then delete -- possibly after reading it to check for error conditions?)

Apart from that, since the main problem is the fact that your perl script is running in an environment where all output to STDOUT goes to some browser client, what you have to do is to change the STDOUT file handle so that stuff written to that handle will end up somewhere else, like a scalar variable (read the output of perldoc -f open):

close STDOUT; open STDOUT, '>', \$variable; system( $command ); close STDOUT; # you might want to check what got put into $variable... open STDOUT, '>-'; # reopen the real stdout
UPDATE: the above snippet was not tested, and on testing it, it doesn't work as intended. See ikegami's reply to me.

Replies are listed 'Best First'.
Re^2: How to hide system(); output.
by ikegami (Patriarch) on Jan 30, 2010 at 04:40 UTC

    open STDOUT, '>', \$variable;

    That won't work. That Perl file handle doesn't have a system file handle associated with it, so the child can't see it. You could use

    $variable = `$command`;
      Oops. Thanks for pointing that out. (I should have tested before posting.)

      While we're at it (now that I have tried it out), there's another aspect of my snippet that didn't work as I expected: re-opening STDOUT that way does not seem to put things back the way they were:

      #!/usr/bin/perl warn "\n==normal case:\n"; print "running ls:\n"; system( "ls" ); close STDOUT; warn "\n==STDOUT closed:\n"; print "running ls a 2nd time\n"; system( "ls" ); open STDOUT, '>-'; warn "\n==STDOUT reopened:\n"; print "running ls a 3rd time\n"; system( "ls" );

      When I run that in at terminal shell, the only output I get on STDOUT comes from the "normal case", nothing shows up after the second and third "warn" messages (bummer).

      I had to read farther into the manual description of open to get it right:

      #!/usr/bin/perl warn "\n==normal case:\n"; print "running ls:\n"; system( "ls" ); open my $oldout, ">&STDOUT"; # "dup" the stdout filehandle close STDOUT; warn "\n==STDOUT closed:\n"; print "running ls a 2nd time\n"; system( "ls" ); open STDOUT, '>&', $oldout; # restore the dup'ed filehandle to STDOUT warn "\n==STDOUT reopened:\n"; print "running ls a 3rd time\n"; system( "ls" );
      (updated to add comments)

      That sort of thing could make a big difference in the OP's situation, where there might be other stuff to be written back to a browser after running a system call.

        this doesnt work on XP+Strawberry perl
Re^2: How to hide system(); output.
by crashtest (Curate) on Jan 30, 2010 at 01:31 UTC

    Maybe the default "cmd.exe" (or whatever gets used on windows to run commands via the system() call) provides some equivalent sort of idiom, if you know how to look that up...

    The equivalent on Windows (at least my cmd.exe) would be:

    $command = "ipconfig >nul 2>1";

      Each suggestion worked equally. Thank you both for the fast help.