Kazama Seiji
2017-09-11 15:06:44 UTC
Hey guys.
I've got such code sample:
timeout 5 tail -fn0 access.log | awk '{print $1}'
It listens to nginx's access.log for 5 secs and outputs the log's first
column (=client IP).
The sample works the same in interactive shell as well as a standalone
script.
But as only I add more stages to the pipe it fails in interactive shell
like in:
timeout 5 tail -fn0 access.log | awk '{print $1}' | wc -l
or
timeout 5 tail -fn0 access.log | awk '{print $1}' | sort | uniq -c |
sort -k1,1nr -k2,2V
the output is a single line "Terminated". It still works as a standalone
script though.
I've figured out the enabled monitor=on bash setting for interactive
mode triggers the behavior. So with "set +m" applied it works in
interactive shell. Another way to overcome it in interactive shell is
such trick
( timeout 5 tail -fn0 access.log; true ) | awk '{print $1}' | wc -l
The question is: what is so special to pipes of 3+ stages that it
presents different behavior vs a 2-stage pipe when monitor=on in bash?
E.g. why this works
set -m
timeout 5 tail -fn0 access.log | awk '{print $1}'
but this doesn't
set -m
timeout 5 tail -fn0 access.log | awk '{print $1}' | wc -l
(I explicitly set monitor=on above for clarity.)
I've got such code sample:
timeout 5 tail -fn0 access.log | awk '{print $1}'
It listens to nginx's access.log for 5 secs and outputs the log's first
column (=client IP).
The sample works the same in interactive shell as well as a standalone
script.
But as only I add more stages to the pipe it fails in interactive shell
like in:
timeout 5 tail -fn0 access.log | awk '{print $1}' | wc -l
or
timeout 5 tail -fn0 access.log | awk '{print $1}' | sort | uniq -c |
sort -k1,1nr -k2,2V
the output is a single line "Terminated". It still works as a standalone
script though.
I've figured out the enabled monitor=on bash setting for interactive
mode triggers the behavior. So with "set +m" applied it works in
interactive shell. Another way to overcome it in interactive shell is
such trick
( timeout 5 tail -fn0 access.log; true ) | awk '{print $1}' | wc -l
The question is: what is so special to pipes of 3+ stages that it
presents different behavior vs a 2-stage pipe when monitor=on in bash?
E.g. why this works
set -m
timeout 5 tail -fn0 access.log | awk '{print $1}'
but this doesn't
set -m
timeout 5 tail -fn0 access.log | awk '{print $1}' | wc -l
(I explicitly set monitor=on above for clarity.)