help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Why using head in different ways will not terminate in t


From: Bob Proulx
Subject: Re: [Help-bash] Why using head in different ways will not terminate in the same time?
Date: Sun, 27 Mar 2016 14:24:02 -0600
User-agent: Mutt/1.5.24 (2015-08-30)

Pierre Gaston wrote:
> Ehsan Hajiramezanali wrote:
> > The following way of calling `head` will terminate as soon as possible:
> >
> > head -n 1 <(echo 1; sleep 10; seq 10)

That is a clever workaround.  One that I hadn't thought of with my
previous response.  This uses process substitution to run the right
hand side part in the background as an asynchronous subprocess which
runs in the background.  Because it is running in the background the
shell doesn't wait for it.  And it proves that head is exiting as soon
as possible.

After running that command if you run 'ps' immediately you will see
that the sleep process, and associated bash shell interpretting the
command, is still running.

  $ head -n 1 <(echo 1; sleep 10; seq 10)
  1
  $ ps
    PID TTY          TIME CMD
   6164 pts/19   00:00:00 bash
   6205 pts/19   00:00:00 bash
   6206 pts/19   00:00:00 sleep
   6217 pts/19   00:00:00 ps

It is basically equivalent to this series of commands.

  $ mkfifo pipe
  $ ( { echo 1; sleep 10; seq 10;} > pipe & head -n1 pipe )
  1

Because the sleep pipeline is running in the background it will
continue to run until it has exited.  (I used a subshell as a simple
way to avoid the shell job control monitoring "[1] 7844" output.)

This shell does something similar to this:

  mkfifo pipe
  { echo 1; sleep 10; seq 10;} > pipe &
  head -n1 pipe
  rm pipe

Depending upon your circumstances it might not be a good thing to be
stacking up these longer running background processes.

> > However, the original command using the following pipeline does not
> > work as what I want, i.e. `head` will wait until `sleep` is finished.

Sorry but no.  As previously noted the head IS exiting.  (Did you not
see the previous messages?)  Why do you think it is still running?  It
is not as can be easily seen in a ps listing.

The shell is waiting for the sleep to finish because it is running in
the foreground.

> > (echo 1; sleep 10; seq 10) | head -n 1

Try that same command without the head but with 'true' which of course
will exit immediately.

  (echo 1; sleep 10; seq 10) | true

The shell still waits for the entire command pipeline to finish
because the sleep is still running in the foreground.

> > It only needs the output from the first echo command. It is
> > unnecessary that it waits until `sleep` is finished. I am wondering
> > if this problem is related with the shell or the other things.
>
> It's not really a problem, it's just the way the shell is implemented.
> 
> In the second case the shell waits for the whole pipeline to exit before
> going on.

Agreed.

> When the right hand side exits nothing happens to the left hand side until
> it tries to write to the pipe in which case it will receive "SIGPIPE"

Agreed.  If there was a way to have the process that sleep is a
surrogate for write significant output then it would detect that the
right hand side had exited.  Perhaps turning on a debug flag would
have it write more output?

Bob



reply via email to

[Prev in Thread] Current Thread [Next in Thread]