Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

dumb question on exec and system ...

by iza (Monk)
on Apr 15, 2004 at 14:29 UTC ( [id://345391]=perlquestion: print w/replies, xml ) Need Help??

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

hi all monks :)
I was wondering how (from a perl script) I could run a DOS command and then redirect STDOUT and STDERR to a file. I read the perldoc and come to the exec() and system() functions, and it - the doc for perlfunc::system - says that I definitly should use qx//. And no surprise, as expected, it works perfectly (I *DO* love perl ! ).
But now I can't help wondering : why do we need the exec() and system() function then - why couldn't we always use ` ? is that only to get some kind of return code ? or is that so we can have "more than one way to" call a system function ? or is that a trap to catch every person asking as dumb questions as I do ?

Replies are listed 'Best First'.
Re: dumb question on exec and system ...
by Abigail-II (Bishop) on Apr 15, 2004 at 14:43 UTC
    exec() replaces the current program by another one. Unless the exec fails to start the mentioned program, exec will not return..

    system() calls another program, and then returns a status code (which contains the exit value of the program, and possibly information about signals). system() can be called in such a way that no shell will be used.

    qx calls another program, and returns the output of that program. It's not under the programmers control whether a shell can be bypassed or not.

    Both system and qx are implemented using fork and exec (at least, under Unix).

    Abigail

      Thanks, it's a nice explanation - clear and short, sums up the doc wonderfully :)
Re: dumb question on exec and system ...
by eXile (Priest) on Apr 15, 2004 at 15:07 UTC
    And you can also use the 'open' command to run another command and redirect it's STDOUT. From the 'perlipc' manpage:
    Using open() for IPC Perl's basic open() statement can also be used for unidirection +al interprocess communication by either appending or prepending a +pipe symbol to the second argument to open(). Here's how to start s +omething up in a child process you intend to write to: open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") || die "can't fork: $!"; local $SIG{PIPE} = sub { die "spooler pipe broke" }; print SPOOLER "stuff\n"; close SPOOLER || die "bad spool: $! $?"; And here's how to start up a child process you intend to read f +rom: open(STATUS, "netstat -an 2>&1 |") || die "can't fork: $!"; while (<STATUS>) { next if /^(tcp|udp)/; print; } close STATUS || die "bad netstat: $! $?";
    For STDIN / STDOUT / STDERR at the same time you could use the IPC::Open3 module:
    use IPC::Open3; $pid = open3(\*WTRFH, \*RDRFH, \*ERRFH, 'some cmd and args', 'optarg', ...);
    TMTOWTDI
      Thanks for the reply - i had read about that one in the doc too ... TMTOWTDI, definitly !!!!
Re: dumb question on exec and system ...
by tilly (Archbishop) on Apr 15, 2004 at 15:32 UTC
    What if the program that you run wants to interact with the user?

    What if you want the messages that your subprocess generates to go to your STDOUT (which, perhaps, is going to a log) as it is generated? (With `` you'll not get any output until the program has completely finished, so no partial progress information is provided.)

    Both of these are good reasons to use system or exec instead of backticks.

      And even if none of these stand, qx captures and saves the output in memory, thus it can eat too much memory unneccessarily if you discard the output. (A make command can have several megs of output to stdout.)

        And even if none of these stand, qx captures and saves the output in memory, thus it can eat too much memory unneccessarily if you discard the output.
        Uhm, no. Testing seems to indicate qx// is context aware, and doesn't store anything in void context. Running:
        perl -wle '`perl -le "print q!*! x 1_000_000 while 1"`'
        doesn't consume much memory, but running
        perl -wle '$_ = `perl -le "print q!*! x 1_000_000 while 1"`'
        quickly consumes all memory available.

        Abigail

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (2)
As of 2024-04-20 03:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found