in reply to Executing Commands with "open"

Since even when we use the open method, isnt the entire output being stored somewhere and then being fetched to be printed out line by line?? If thats the case dont they use up the same amount of memory?

No, the data isn't stored anywhere.

In both case, the data is passed to Perl via a pipe (64k buffer?). The backticks empties the pipe into a scalar (or scalars in list context), where as the open method provides you a handle to the pipe so you can empty it yourself. The child will block if it tries to write to a full pipe.

Note that this form of open returns a pid, and you should call waitpid($pid, 0); to release the resource used by the child.

Replies are listed 'Best First'.
Re^2: Executing Commands with "open"
by abhijithtk (Novice) on Jun 14, 2010 at 16:11 UTC

    Where is this buffer?? Doesnt it count as memory? or is it a physical memory location..?

    So according to what you said the output is stored in this buffer. Backticks empty them into a scalar all at once.

    Incase of open, on calling the open statement, the command gets executed and the output is stored in the buffer, and the filehandle is for the buffer?? :)

    Have i understood it correct?
      Where is this buffer?
      Handled by the kernel.
      Doesnt it count as memory?
      It does. Just not Perl memory (which means, you can store a lot more data for the same amount of memory ;-))
      So according to what you said the output is stored in this buffer. Backticks empty them into a scalar all at once.
      Yes, which gives another difference (and, IMO, the most important difference) between a pipe read and backticks: with backticks, the entire output is collected first - that is, the called program has to finish first before the Perl program can continue; with a pipe, the Perl program can do something as soon as a line of data becomes available.
      Incase of open, on calling the open statement, the command gets executed and the output is stored in the buffer, and the filehandle is for the buffer?? :)
      Sort of. Both the command and the Perl program can run in parallel. And the handle you're getting isn't quite the same as a handle you're getting when opening a file. You cannot seek() a buffer, for instance.

      Where is this buffer??

      It's part of the system file handle.

      Doesnt it count as memory?

      It holds data, so it's some form of memory by definition.

      But it's a rather small (64k?), fixed-size buffer.

      So according to what you said the output is stored in this buffer. Backticks empty them into a scalar all at once.

      No. That would require the output of the child to fit in the buffer, but that's impossible since it's a fixed-size buffer. Backticks repeatedly and continually empty the pipe into a scalar. Backticks is more or less equivalent to

      my $pid = open(my $fh, '-|', $cmd); my $scalar = ''; 1 while sysread($fh, $scalar, BLK_SIZE, length($scalar)); waitpid($pid, 0); return $scalar;

      The scalar keep growing and growing.

      Update: Added the first two answers.

        (64k?)

        Seems to be 12k?

        C:\>perl -E"$s='x'x1024; say $s, warn $_ for 1 .. 100" | perl -nle" sl +eep 100" 1 at -e line 1. 2 at -e line 1. 3 at -e line 1. 4 at -e line 1. 5 at -e line 1. 6 at -e line 1. 7 at -e line 1. 8 at -e line 1. 9 at -e line 1. 10 at -e line 1. 11 at -e line 1. 12 at -e line 1.

        Update: I think 4K at each end and 4k in the middle.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        Thanks Guys..

        Sort of Making Sense now...