commands, which is better

Discussion in 'Perl Misc' started by Robert Wallace, Oct 21, 2003.

  1. i'm trying to run a system command like ls,dir,ping,uptime, etc...

    I tried the following two methods. both works. both produce the same
    output.
    is there a difference? is there a situation where I would use one over
    the other?
    I guess the open allows me to do more on-the-fly stuff.
    what else?



    # this one ##########################################################
    open (SYS, "/temp/uptime.exe |");
    while($the_sys = <SYS>){
    $the_sys =~ s/\015\012/<br>\015\012/g;
    print $the_sys . "<br>\n";
    }
    close (SYS);


    # and this one
    ##########################################################
    $sys=`/temp/uptime.exe`;
    $sys=~s/\015\012/<br>\015\012/g;
    print $sys;
     
    Robert Wallace, Oct 21, 2003
    #1
    1. Advertising

  2. Robert Wallace

    Anand Guest

    second one will fork new process as you are using *NIX thing. If you do
    not want to create new process (which will take some or more system
    resources) you are better off using PURE perl as in case of first example.

    --Anand

    Robert Wallace wrote:

    > i'm trying to run a system command like ls,dir,ping,uptime, etc...
    >
    > I tried the following two methods. both works. both produce the same
    > output.
    > is there a difference? is there a situation where I would use one over
    > the other?
    > I guess the open allows me to do more on-the-fly stuff.
    > what else?
    >
    >
    >
    > # this one ##########################################################
    > open (SYS, "/temp/uptime.exe |");
    > while($the_sys = <SYS>){
    > $the_sys =~ s/\015\012/<br>\015\012/g;
    > print $the_sys . "<br>\n";
    > }
    > close (SYS);
    >
    >
    > # and this one
    > ##########################################################
    > $sys=`/temp/uptime.exe`;
    > $sys=~s/\015\012/<br>\015\012/g;
    > print $sys;
     
    Anand, Oct 21, 2003
    #2
    1. Advertising

  3. Robert Wallace <> writes:
    [snip]
    > is there a difference? is there a situation where I would use one over
    > the other?

    [snip]
    > # this one ##########################################################
    > open (SYS, "/temp/uptime.exe |");

    [snip]
    > # and this one
    > $sys=`/temp/uptime.exe`;



    On *NIX, both commands do almost the same. Both fork a child and both execute
    the command in a subshell. The first method reads the output of uptime.exe
    line-by-line, which allows you to close the handle as soon as you read the
    data you're interested in. If tha output of uptime.exe was very long, this
    difference would matter.

    You probably want to read the perlipc manpage.


    --
    Ernst-Udo Wallenborn
     
    Ernst-Udo Wallenborn, Oct 21, 2003
    #3
  4. [ top-posting corrected. ]


    Anand <> wrote:
    > Robert Wallace wrote:


    >> I tried the following two methods. both works. both produce the same
    >> output.
    >> is there a difference?


    >> open (SYS, "/temp/uptime.exe |");


    >> $sys=`/temp/uptime.exe`;



    > second one will fork new process as you are using *NIX thing.



    So will the first one.

    Neither of them does the "*NIX thing".

    Nearly every OS needs a process to run a program in.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Oct 21, 2003
    #4
  5. Robert Wallace

    Mina Naguib Guest

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1


    [Please do NOT top-post]

    > Robert Wallace wrote:
    >
    >> i'm trying to run a system command like ls,dir,ping,uptime, etc...
    >>
    >> I tried the following two methods. both works. both produce the same
    >> output.
    >> is there a difference? is there a situation where I would use one over
    >> the other? I guess the open allows me to do more on-the-fly stuff.
    >> what else?
    >>
    >>
    >>
    >> # this one ##########################################################
    >> open (SYS, "/temp/uptime.exe |");
    >> while($the_sys = <SYS>){
    >> $the_sys =~ s/\015\012/<br>\015\012/g;
    >> print $the_sys . "<br>\n";
    >> }
    >> close (SYS);
    >>
    >>
    >> # and this one
    >> ##########################################################
    >> $sys=`/temp/uptime.exe`;
    >> $sys=~s/\015\012/<br>\015\012/g;
    >> print $sys;

    >
    >

    Anand wrote:
    > second one will fork new process as you are using *NIX thing. If you do
    > not want to create new process (which will take some or more system
    > resources) you are better off using PURE perl as in case of first example.
    >
    > --Anand
    >


    That's not correct. The first example also forks a second process.

    The only difference is in the first example you're reading the output yourself line-by-line, while
    with the second example perl does that job for you and returns the whole output in one chunk.

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.1 (GNU/Linux)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iD8DBQE/lW/eeS99pGMif6wRAph4AJ9vkInKaXZZ/y9385wblxpAqYgj1wCeIDVI
    Sxfis+WkDK9psa5bc1yuYmU=
    =wcX4
    -----END PGP SIGNATURE-----
     
    Mina Naguib, Oct 21, 2003
    #5
  6. Robert Wallace

    Tedd Hansen Guest

    Using the first one, Perl receives data directly and you process it line by
    line.
    Using the second method will give the OS (and Perl) a chance to buffer data
    and write chunks to your variable.

    The first example;
    + You can analyze data as it arrives
    + You can terminate the application at any time using close()
    - Using the usual "while <>" eats much CPU, so not so good when receiving
    big amounts of data that isn't meant for line-by-linbe processing (my
    theory)
    + You can use (binmode() and) sysread() to simulate the second example
    + Lets you pipe data TO the command (| command)

    The second example;
    - Your application blocks until the command you are running terminates (can
    be bypassed by alarm())
    - You can't terminate the command you are running (unless you trace it's
    PID)
    - You must write your own process-line-by-line-code if required
    - If the command returns loads of data, it eats up memory
    + Takes up less CPU in some cases where you don't want to process the
    feedback line by line (my theory)

    Also consider the more secure (in form of argument parsing):
    system($cmd, $param1, $param2, @params)
    and related
    exec()
    open(FH, "|-") (fork perl with a filehandle piped to STDINPUT and STDOUTPUT
    of the child)


    Remember when executing commands that a fork is actually a fork followed by
    a complete overwrite of the program's code. This means that on operating
    systems where Perl has problems with forking and signaling you need to
    consider this. There are some simple workarounds, the most famous;

    sub REAPER {
    $waitedpid = wait;
    }

    $SIG{CHLD} = \&REAPER;
    # Now execute commands or fork or something



    "Robert Wallace" <> wrote in message
    news:...
    > i'm trying to run a system command like ls,dir,ping,uptime, etc...
    >
    > I tried the following two methods. both works. both produce the same
    > output.
    > is there a difference? is there a situation where I would use one over
    > the other?
    > I guess the open allows me to do more on-the-fly stuff.
    > what else?
    >
    >
    >
    > # this one ##########################################################
    > open (SYS, "/temp/uptime.exe |");
    > while($the_sys = <SYS>){
    > $the_sys =~ s/\015\012/<br>\015\012/g;
    > print $the_sys . "<br>\n";
    > }
    > close (SYS);
    >
    >
    > # and this one
    > ##########################################################
    > $sys=`/temp/uptime.exe`;
    > $sys=~s/\015\012/<br>\015\012/g;
    > print $sys;
     
    Tedd Hansen, Oct 21, 2003
    #6
  7. Tedd Hansen wrote:
    >
    > Using the first one, Perl receives data directly and you process it line by
    > line.
    > Using the second method will give the OS (and Perl) a chance to buffer data
    > and write chunks to your variable.

    ......


    whoa
    thanks for the analysis folks
    looks like i've got a load of research ahead of me.
     
    Robert Wallace, Oct 22, 2003
    #7
  8. Robert Wallace

    Greg Miller Guest

    On Tue, 21 Oct 2003 10:44:42 -0400, Robert Wallace
    <> wrote:

    ># this one ##########################################################
    >open (SYS, "/temp/uptime.exe |");
    >while($the_sys = <SYS>){
    > $the_sys =~ s/\015\012/<br>\015\012/g;
    > print $the_sys . "<br>\n";
    >}
    >close (SYS);
    >
    >
    ># and this one
    >##########################################################
    >$sys=`/temp/uptime.exe`;
    >$sys=~s/\015\012/<br>\015\012/g;
    >print $sys;


    In addition to what they others said: in the first example,
    if the output of the uptime.exe program pauses long enough for the
    perl program to catch up, the while loop will terminate even if the
    program outputs more data later. IIRC

    Greg Miller http://www.gregmiller.net
     
    Greg Miller, Oct 23, 2003
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Pfaff

    Re: man pages for C commands (GCC commands)

    Ben Pfaff, Jun 24, 2003, in forum: C Programming
    Replies:
    4
    Views:
    3,973
    Thomas Stegen
    Jun 28, 2003
  2. Tim Stanka
    Replies:
    1
    Views:
    804
    Jeff Epler
    Aug 2, 2004
  3. Peter Bencsik
    Replies:
    2
    Views:
    835
  4. Tobias Reif
    Replies:
    6
    Views:
    119
    Tobias Reif
    Sep 3, 2003
  5. Ma Sa
    Replies:
    15
    Views:
    191
    Lionel Bouton
    Mar 6, 2008
Loading...

Share This Page