FAQ
Greetings,

The pipe package (http://labix.org/pipe) received a number of
improvements, and v2 is out to avoid breaking existing apps with the
changes made.

Here is the change list:

- Some bug fixes (v1 got these as well).

- The Flusher interface is now Task, its Flush method is now Run, and
related methods/functions were changed accordingly. This is a better
representation of the model (and solves your worries, Roger).

     http://labix.org/v2/pipe#Task
     http://labix.org/v2/pipe#State

- The DisjointOutput function was renamed to DividedOutput (suggested
by Kamil Kisiel).

     http://labix.org/v2/pipe#DividedOutput

- Added RenameFile, useful for atomic replacements right after
flushing a stream:

     http://labix.org/v2/pipe#RenameFile

- Added AppendFile, to stream content to the end of a file.

     http://labix.org/v2/pipe#AppendFile

- Filter's line argument is now a []byte. The previous implementation
was producing garbage unnecessarily.

     http://labix.org/v2/pipe#Filter

- New Replace function is the generic form of Filter. It allows
replacing, deleting, and adding new ones.

     http://labix.org/v2/pipe#Replace

- The pipe running methods now return the slice-based error type
pipe.Errors when errors happen, so that concurrently executed
pipelines can report multiple issues and avoid hiding the real problem
(this was also applied to v1).

     http://labix.org/v2/pipe#Errors

- TeeFile was renamed TeeWriteFile, and TeeAppendFile was added.

     http://labix.org/v2/pipe#TeeWriteFile
     http://labix.org/v2/pipe#TeeAppendFile

- Added RenameFile to simplify atomic replacements after streams are flushed.

     http://labix.org/v2/pipe#RenameFile


gustavo @ http://niemeyer.net

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Job van der Zwan at Apr 22, 2013 at 12:52 am
    This might sound like a ridiculous thing to compliment, but I really like
    the aesthetics of your source code.

    http://bazaar.launchpad.net/+branch/pipe/v2/view/head:/pipe.go
    On Monday, 22 April 2013 01:06:51 UTC+2, Gustavo Niemeyer wrote:

    Greetings,

    The pipe package (http://labix.org/pipe) received a number of
    improvements, and v2 is out to avoid breaking existing apps with the
    changes made.

    Here is the change list:

    - Some bug fixes (v1 got these as well).

    - The Flusher interface is now Task, its Flush method is now Run, and
    related methods/functions were changed accordingly. This is a better
    representation of the model (and solves your worries, Roger).

    http://labix.org/v2/pipe#Task
    http://labix.org/v2/pipe#State

    - The DisjointOutput function was renamed to DividedOutput (suggested
    by Kamil Kisiel).

    http://labix.org/v2/pipe#DividedOutput

    - Added RenameFile, useful for atomic replacements right after
    flushing a stream:

    http://labix.org/v2/pipe#RenameFile

    - Added AppendFile, to stream content to the end of a file.

    http://labix.org/v2/pipe#AppendFile

    - Filter's line argument is now a []byte. The previous implementation
    was producing garbage unnecessarily.

    http://labix.org/v2/pipe#Filter

    - New Replace function is the generic form of Filter. It allows
    replacing, deleting, and adding new ones.

    http://labix.org/v2/pipe#Replace

    - The pipe running methods now return the slice-based error type
    pipe.Errors when errors happen, so that concurrently executed
    pipelines can report multiple issues and avoid hiding the real problem
    (this was also applied to v1).

    http://labix.org/v2/pipe#Errors

    - TeeFile was renamed TeeWriteFile, and TeeAppendFile was added.

    http://labix.org/v2/pipe#TeeWriteFile
    http://labix.org/v2/pipe#TeeAppendFile

    - Added RenameFile to simplify atomic replacements after streams are
    flushed.

    http://labix.org/v2/pipe#RenameFile


    gustavo @ http://niemeyer.net
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Kyle Lemons at Apr 22, 2013 at 1:13 am

    On Sun, Apr 21, 2013 at 5:52 PM, Job van der Zwan wrote:

    This might sound like a ridiculous thing to compliment, but I really like
    the aesthetics of your source code.

    Definitely not a ridiculous thing to compliment, actually :). I think
    readable code is very important, and really appreciate the care that the Go
    team has taken to make a standard library that sets a good example and
    tools that help make this easier.

    http://bazaar.launchpad.net/+branch/pipe/v2/view/head:/pipe.go

    On Monday, 22 April 2013 01:06:51 UTC+2, Gustavo Niemeyer wrote:

    Greetings,

    The pipe package (http://labix.org/pipe) received a number of
    improvements, and v2 is out to avoid breaking existing apps with the
    changes made.

    Here is the change list:

    - Some bug fixes (v1 got these as well).

    - The Flusher interface is now Task, its Flush method is now Run, and
    related methods/functions were changed accordingly. This is a better
    representation of the model (and solves your worries, Roger).

    http://labix.org/v2/pipe#Task
    http://labix.org/v2/pipe#State

    - The DisjointOutput function was renamed to DividedOutput (suggested
    by Kamil Kisiel).

    http://labix.org/v2/pipe#**DividedOutput<http://labix.org/v2/pipe#DividedOutput>

    - Added RenameFile, useful for atomic replacements right after
    flushing a stream:

    http://labix.org/v2/pipe#**RenameFile<http://labix.org/v2/pipe#RenameFile>

    - Added AppendFile, to stream content to the end of a file.

    http://labix.org/v2/pipe#**AppendFile<http://labix.org/v2/pipe#AppendFile>

    - Filter's line argument is now a []byte. The previous implementation
    was producing garbage unnecessarily.

    http://labix.org/v2/pipe#**Filter <http://labix.org/v2/pipe#Filter>

    - New Replace function is the generic form of Filter. It allows
    replacing, deleting, and adding new ones.

    http://labix.org/v2/pipe#**Replace <http://labix.org/v2/pipe#Replace>

    - The pipe running methods now return the slice-based error type
    pipe.Errors when errors happen, so that concurrently executed
    pipelines can report multiple issues and avoid hiding the real problem
    (this was also applied to v1).

    http://labix.org/v2/pipe#**Errors <http://labix.org/v2/pipe#Errors>

    - TeeFile was renamed TeeWriteFile, and TeeAppendFile was added.

    http://labix.org/v2/pipe#**TeeWriteFile<http://labix.org/v2/pipe#TeeWriteFile>
    http://labix.org/v2/pipe#**TeeAppendFile<http://labix.org/v2/pipe#TeeAppendFile>

    - Added RenameFile to simplify atomic replacements after streams are
    flushed.

    http://labix.org/v2/pipe#**RenameFile<http://labix.org/v2/pipe#RenameFile>


    gustavo @ http://niemeyer.net
    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Gustavo Niemeyer at Apr 22, 2013 at 1:23 am

    On Sun, Apr 21, 2013 at 9:52 PM, Job van der Zwan wrote:
    This might sound like a ridiculous thing to compliment, but I really like
    the aesthetics of your source code.
    That's very kind. Thanks Job.


    gustavo @ http://niemeyer.net

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Ingo Oeser at Apr 22, 2013 at 1:38 am
    Hi Gustavo,

    just wanted to say: awesome package!

    Very useful to replace legacy shell scripts step by step with a Go program.

    Best Regards

    Ingo

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Chris Hines at Apr 10, 2014 at 3:12 pm

    On Sunday, April 21, 2013 7:06:51 PM UTC-4, Gustavo Niemeyer wrote:
    Greetings,

    The pipe package (http://labix.org/pipe) received a number of
    improvements, and v2 is out to avoid breaking existing apps with the
    changes made.
    As I posted on G+<https://plus.google.com/u/0/+ChrisHines/posts/NeVWGLq9rXT> recently,
    this package has been really useful for a project I've been working on.

    Since that post I discovered a need to kill a running if any of the steps
    takes too long to complete.

    Initially I was disappointed that I couldn't kill a running pipe, but then
    I noticed that pipe.Task has a Kill method and that State.RunTasks() kills
    pending tasks when a task returns an error. These observations allowed me
    to make a trivial implementation of a Timeout task that I'd like to share
    and get feedback on.

    Specifically I am curious if it would be better to create a new type that
    implements pipe.Task directly instead of using pipe.TaskFunc. Implementing
    pipe.Task would allow stopping the timeout timer if the Kill method is
    called due to another task a pipe.Line returning an error before the
    timeout expired. I'm not sure if that really matters, though.

    For Gustavo specifically, is this a capability you would like to add
    directly to the pipe package, or do you consider it out of scope and up to
    someone else to provide?

    Thanks,
    Chris

    http://play.golang.org/p/9RIIKGzwnU

    package pipeutil

    import (
    "fmt"
    "io"
    "time"

    "labix.org/v2/pipe"
    )

    func Timeout(dur time.Duration) pipe.Pipe {
    return pipe.TaskFunc(func(s *pipe.State) error {
    done := make(chan struct{})
    go func() {
    io.Copy(s.Stdout, s.Stdin)
    close(done)
    }()
    select {
    case <-time.After(dur):
    return fmt.Errorf("timeout after %v", dur)
    case <-done:
    return nil
    }
    })
    }

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dmitri Shuralyov at Apr 11, 2014 at 5:50 am
    Hey Chris,

    I've been talking with Gustavo about a similar need I had: an API to
    externally interrupt/kill a running pipe. We agreed that it'd be a
    worthwhile addition, and he encouraged me to give it a try since he was
    busy at the time (https://twitter.com/gniemeyer/status/447261648378920960).

    You can see my fork where I've added a Kill()
    API: https://github.com/shurcooL/pipe/commit/81223b822d0a375670d4a2f6ac4804b2c0a9cc75

    Sample
    usage: https://github.com/shurcooL/play/blob/8cf64e62c0e3801051cae964500e090db772bb46/14/main.go#L23-L27

    It works great in my use so far (mostly for os.Exec process tasks).

    I currently have some uncommitted changes where I was trying to add a way
    for goroutine tasks to query if the pipe has been Kill'ed, and if so, they
    can choose to return early (since there's no other way to kill a running
    goroutine - it can only be done if the goroutine task periodically
    voluntarily checks if it should keep running), but I haven't come to the
    cleanest solution for that yet...

    Let me know your thoughts on this.

    On Thursday, April 10, 2014 8:12:40 AM UTC-7, Chris Hines wrote:
    On Sunday, April 21, 2013 7:06:51 PM UTC-4, Gustavo Niemeyer wrote:

    Greetings,

    The pipe package (http://labix.org/pipe) received a number of
    improvements, and v2 is out to avoid breaking existing apps with the
    changes made.
    As I posted on G+<https://plus.google.com/u/0/+ChrisHines/posts/NeVWGLq9rXT> recently,
    this package has been really useful for a project I've been working on.

    Since that post I discovered a need to kill a running if any of the steps
    takes too long to complete.

    Initially I was disappointed that I couldn't kill a running pipe, but then
    I noticed that pipe.Task has a Kill method and that State.RunTasks() kills
    pending tasks when a task returns an error. These observations allowed me
    to make a trivial implementation of a Timeout task that I'd like to share
    and get feedback on.

    Specifically I am curious if it would be better to create a new type that
    implements pipe.Task directly instead of using pipe.TaskFunc. Implementing
    pipe.Task would allow stopping the timeout timer if the Kill method is
    called due to another task a pipe.Line returning an error before the
    timeout expired. I'm not sure if that really matters, though.

    For Gustavo specifically, is this a capability you would like to add
    directly to the pipe package, or do you consider it out of scope and up to
    someone else to provide?

    Thanks,
    Chris

    http://play.golang.org/p/9RIIKGzwnU

    package pipeutil

    import (
    "fmt"
    "io"
    "time"

    "labix.org/v2/pipe"
    )

    func Timeout(dur time.Duration) pipe.Pipe {
    return pipe.TaskFunc(func(s *pipe.State) error {
    done := make(chan struct{})
    go func() {
    io.Copy(s.Stdout, s.Stdin)
    close(done)
    }()
    select {
    case <-time.After(dur):
    return fmt.Errorf("timeout after %v", dur)
    case <-done:
    return nil
    }
    })
    }
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Tamás Gulácsi at Apr 11, 2014 at 6:23 am
    What about a channel on which all pipe tasks select for being closed?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris Hines at Apr 11, 2014 at 3:13 pm
    Dmitry,

    I took a look at your fork. Your implementation of State.Kill() looks good
    to me, and is almost exactly as I imagined it would be after reading your
    message.

    But the example of use is a bit less satisfying. Here is the example for
    reference:

    func ChanCombinedOutput(outch ChanWriter, p pipe.Pipe) error {
      s := pipe.NewState(outch, outch)

      // Test interrupting the pipe after a few seconds.
      go func() {
       time.Sleep(5 * time.Second)
       s.Kill()
      }()

      err := p(s) // 1
      if err == nil {
       err = s.RunTasks()
      }
      close(outch)
      return err
    }


    It is not satisfying partly because the existing documentation of
    State.RunTasks says, "RunTasks runs all pending tasks registered via
    AddTask. This is called by the pipe running functions and generally there's
    no reason to call it directly." It also took me a few moments to understand
    the significance of the line I've marked with // 1. The pipe package has
    several subtleties to it, but the fact that a Pipe is a function that
    doesn't run the process but rather just configures it to be run, and that
    the State is what actually manages a running Pipe has taken me a while to
    appreciate.

    Unfortunately I'm not sure how to improve on the example. I've tried
    writing it a few different ways, but all of my attempts had significant
    flaws.

    Perhaps a good example of how to Kill a running pipe in the docs will be
    sufficient.

    Chris
    On Friday, April 11, 2014 1:50:37 AM UTC-4, Dmitri Shuralyov wrote:

    Hey Chris,

    I've been talking with Gustavo about a similar need I had: an API to
    externally interrupt/kill a running pipe. We agreed that it'd be a
    worthwhile addition, and he encouraged me to give it a try since he was
    busy at the time (https://twitter.com/gniemeyer/status/447261648378920960
    ).

    You can see my fork where I've added a Kill() API:
    https://github.com/shurcooL/pipe/commit/81223b822d0a375670d4a2f6ac4804b2c0a9cc75

    Sample usage:
    https://github.com/shurcooL/play/blob/8cf64e62c0e3801051cae964500e090db772bb46/14/main.go#L23-L27

    It works great in my use so far (mostly for os.Exec process tasks).

    I currently have some uncommitted changes where I was trying to add a way
    for goroutine tasks to query if the pipe has been Kill'ed, and if so, they
    can choose to return early (since there's no other way to kill a running
    goroutine - it can only be done if the goroutine task periodically
    voluntarily checks if it should keep running), but I haven't come to the
    cleanest solution for that yet...

    Let me know your thoughts on this.

    On Thursday, April 10, 2014 8:12:40 AM UTC-7, Chris Hines wrote:
    On Sunday, April 21, 2013 7:06:51 PM UTC-4, Gustavo Niemeyer wrote:

    Greetings,

    The pipe package (http://labix.org/pipe) received a number of
    improvements, and v2 is out to avoid breaking existing apps with the
    changes made.
    As I posted on G+<https://plus.google.com/u/0/+ChrisHines/posts/NeVWGLq9rXT> recently,
    this package has been really useful for a project I've been working on.

    Since that post I discovered a need to kill a running if any of the steps
    takes too long to complete.

    Initially I was disappointed that I couldn't kill a running pipe, but
    then I noticed that pipe.Task has a Kill method and that State.RunTasks()
    kills pending tasks when a task returns an error. These observations
    allowed me to make a trivial implementation of a Timeout task that I'd like
    to share and get feedback on.

    Specifically I am curious if it would be better to create a new type that
    implements pipe.Task directly instead of using pipe.TaskFunc. Implementing
    pipe.Task would allow stopping the timeout timer if the Kill method is
    called due to another task a pipe.Line returning an error before the
    timeout expired. I'm not sure if that really matters, though.

    For Gustavo specifically, is this a capability you would like to add
    directly to the pipe package, or do you consider it out of scope and up to
    someone else to provide?

    Thanks,
    Chris

    http://play.golang.org/p/9RIIKGzwnU

    package pipeutil

    import (
    "fmt"
    "io"
    "time"

    "labix.org/v2/pipe"
    )

    func Timeout(dur time.Duration) pipe.Pipe {
    return pipe.TaskFunc(func(s *pipe.State) error {
    done := make(chan struct{})
    go func() {
    io.Copy(s.Stdout, s.Stdin)
    close(done)
    }()
    select {
    case <-time.After(dur):
    return fmt.Errorf("timeout after %v", dur)
    case <-done:
    return nil
    }
    })
    }
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gustavo Niemeyer at Apr 11, 2014 at 1:39 pm
    Hi Chris,
    On Thu, Apr 10, 2014 at 12:12 PM, Chris Hines wrote:
    For Gustavo specifically, is this a capability you would like to add
    directly to the pipe package, or do you consider it out of scope and up to
    someone else to provide?
    As Dmitri mentioned he was also looking for the same thing, and did
    some work towards supporting it already. I'll have a look at that pull
    request and integrate something.


    gustavo @ http://niemeyer.net

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris Hines at Apr 11, 2014 at 3:36 pm
    Gustavo,

    Thanks for taking the time to add this feature, I think it will make the
    pipe package even more useful.

    While we are giving some attention to this package I'll take the time to
    give you some feedback on the documentation. When I started digging into
    the package to use it in a real project I found most of the docs easy to
    understand. I think there are two areas that could be improved, however.

    As a pure user of the package I had some trouble understanding the
    difference between pipe.Line and pipe.Script. Both functions have the same
    signature and are clearly used to compose a sequence of other Pipes, but
    their docs were too subtle for me to understand when to use one over the
    other. Line seemed easy to understand thanks to the first example given at
    http://labix.org/pipe. Showing the code to implement "cat article.ps | lpr"
    is a great analogy that makes it click right away. That left me wondering
    what the use for a Script was. The explanation of the Script example was
    somehow less helpful to me. Meanwhile the godoc for the Line and Script
    respectively say, "Entries are run sequentially, but flushed concurrently,"
    and "Entries are both run and flushed sequentially." I don't find these
    sentences very helpful. In fact the first one seems misleading, since all
    the entries in a Line are running concurrently in their own go routine.

    Having dug into the package code and used it for a while now, I think I
    appreciate the difference between Line and Script now. In my mind the key
    difference is that a Line daisy chains the data streams of each entry and
    the output of the Line is what the last task outputs, while a Script has a
    single Stdin that each task reads from after the prior task has exited, and
    a single Stdout that is the accumulation of the output of each task.

    The second area that I had trouble groking was when I wanted to write my
    own Pipe components. The relationship between Pipes and States was not
    clear to me from the documentation. When simply consuming the existing pipe
    tasks one never encounter a State, which is good, but that meant that I
    didn't appreciate the importance of State and I had to look at the source
    code. Maybe that's acceptable for more advanced uses of the package, but I
    thought it was worth mentioning.

    Thanks again for the great package,
    Chris
    On Friday, April 11, 2014 9:39:07 AM UTC-4, Gustavo Niemeyer wrote:

    Hi Chris,
    On Thu, Apr 10, 2014 at 12:12 PM, Chris Hines wrote:
    For Gustavo specifically, is this a capability you would like to add
    directly to the pipe package, or do you consider it out of scope and up to
    someone else to provide?
    As Dmitri mentioned he was also looking for the same thing, and did
    some work towards supporting it already. I'll have a look at that pull
    request and integrate something.


    gustavo @ http://niemeyer.net
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gustavo Niemeyer at Apr 11, 2014 at 4:58 pm
    Hi Chris,

    On Fri, Apr 11, 2014 at 12:36 PM, Chris Hines wrote:
    Thanks for taking the time to add this feature, I think it will make the
    pipe package even more useful.
    Sounds good. I'll try to work on this over the weekend.

    (...)
    http://labix.org/pipe. Showing the code to implement "cat article.ps | lpr"
    is a great analogy that makes it click right away. That left me wondering
    what the use for a Script was. The explanation of the Script example was
    Script executes the entries in sequence, pretty much as the default
    behavior of a shell script. The equivalent script analogy might be
    simply "echo foo; echo bar".
    somehow less helpful to me. Meanwhile the godoc for the Line and Script
    respectively say, "Entries are run sequentially, but flushed concurrently,"
    and "Entries are both run and flushed sequentially." I don't find these
    sentences very helpful. In fact the first one seems misleading, since all
    the entries in a Line are running concurrently in their own go routine.
    These statements are both correct, but they're useful mainly to
    understand the internals if you want to implement your own Pipe. The
    first part of the documentation in both cases is more relevant if you
    just want to make use of it: Script runs things sequentially, Line
    connects the output of N to the input of N+1.

    With that said, I appreciate the feedback. I'll add some examples to
    the documentation to make things more clear.
    Having dug into the package code and used it for a while now, I think I
    appreciate the difference between Line and Script now. In my mind the key
    difference is that a Line daisy chains the data streams of each entry and
    the output of the Line is what the last task outputs, while a Script has a
    single Stdin that each task reads from after the prior task has exited, and
    a single Stdout that is the accumulation of the output of each task.
    That specific part is not quite right, and I don't blame you as the
    documentation is clearly lacking in that regard. Script behaves in a
    similar way to an actual shell: the tasks run all have the *same*
    stdin and stdout.
    The second area that I had trouble groking was when I wanted to write my own
    Pipe components. The relationship between Pipes and States was not clear to
    me from the documentation. When simply consuming the existing pipe tasks one
    never encounter a State, which is good, but that meant that I didn't
    appreciate the importance of State and I had to look at the source code.
    Maybe that's acceptable for more advanced uses of the package, but I thought
    it was worth mentioning.
    Yeah, the best way to develop custom pipes is likely to read the
    documentation and then look at existing ones. Most of them are very
    straightforward.


    gustavo @ http://niemeyer.net

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris Hines at Apr 11, 2014 at 5:26 pm

    On Friday, April 11, 2014 12:57:57 PM UTC-4, Gustavo Niemeyer wrote:
    Script executes the entries in sequence, pretty much as the default
    behavior of a shell script. The equivalent script analogy might be
    simply "echo foo; echo bar".
    Yes.

    Having dug into the package code and used it for a while now, I think I
    appreciate the difference between Line and Script now. In my mind the key
    difference is that a Line daisy chains the data streams of each entry and
    the output of the Line is what the last task outputs, while a Script has a
    single Stdin that each task reads from after the prior task has exited, and
    a single Stdout that is the accumulation of the output of each task.
    That specific part is not quite right, and I don't blame you as the
    documentation is clearly lacking in that regard. Script behaves in a
    similar way to an actual shell: the tasks run all have the *same*
    stdin and stdout.
    Yes, I think we are saying the same thing.

    Just to clarify, I was trying to convey the idea that having the *same*
    stdin doesn't mean they each get a copy of the same data. Rather, the first
    script step consumes some portion of stdin, and after the first step has
    exited the second step can consume some more from stdin, but doesn't get a
    chance to consume the data that the first step consumed, etc. on down the
    script. Correct?

    I think my challenge understanding pipe.Script had as much to do with my
    scripting background than anything else. Most multi-step shell scripts I
    see tend to be running commands on files rather than consuming stdin and
    producing stdout and it took me a while to see the analogy as a result. I
    don't know if other people will have the same disconnect.

    Chris

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gustavo Niemeyer at Apr 11, 2014 at 5:32 pm

    On Fri, Apr 11, 2014 at 2:26 PM, Chris Hines wrote:
    Just to clarify, I was trying to convey the idea that having the *same*
    stdin doesn't mean they each get a copy of the same data. Rather, the first
    script step consumes some portion of stdin, and after the first step has
    exited the second step can consume some more from stdin, but doesn't get a
    chance to consume the data that the first step consumed, etc. on down the
    script. Correct?
    That's right. Sorry, I misunderstood what you first wrote, but I see
    we both said the same thing.
    I think my challenge understanding pipe.Script had as much to do with my
    scripting background than anything else. Most multi-step shell scripts I see
    tend to be running commands on files rather than consuming stdin and
    producing stdout and it took me a while to see the analogy as a result. I
    don't know if other people will have the same disconnect.
    I'll see if I can add some examples to help with that.


    gustavo @ http://niemeyer.net

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedApr 21, '13 at 11:07p
activeApr 11, '14 at 5:32p
posts14
users7
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase