3

Starting from here I tried to read a file and emit the head and the tail of the file (reading the file only once).

I tried the following: tee >(head) >(tail) > /dev/null < text.txt

This line works as expected, but I'd like to get rid of the /dev/null. So I tried: tee >(head) | tail < text.txt

But this line does not work as expected (well, as I expected), it prints the head but does not return after that. Apparently tail is waiting for something. But I don't know what for exactly. I found this SO question, but I could not get it running with the given answers.

Community
  • 1
  • 1
Bouncner
  • 2,124
  • 1
  • 19
  • 19

1 Answers1

5

In tee >(head) | tail < text.txt, the text file goes directly to tail. You probably meant

tee >(head) < text.txt | tail

Which does not wait for anything, but does not work either, because the output of both tee and head go to tail.

Redirecting the head's output to a new file descriptor and then taking it back works, but I am not sure it is "cleaner" than using /dev/null:

( tee >(head >&3) < text.txt | tail) 3>&1 
codeforester
  • 39,467
  • 16
  • 112
  • 140
choroba
  • 231,213
  • 25
  • 204
  • 289
  • I don't think the output of `head` is affected by the pipe, only the output of `tee`. – chepner May 20 '13 at 19:58
  • @chepner: I created a file with numbers 1..100, then tried `tee >(head -n 3) < text.txt | tail`. – choroba May 20 '13 at 20:01
  • @chepner You're mistaken. Compare the result of `echo -e "a\nb\nc" | tee >(head -1) | tail -1` to the result of `echo -e "a\nb\nc" | tee >(head -2) | tail -1`. – Ansgar Wiechers May 20 '13 at 20:03
  • I get `a\nc\n` vs `a\nb\n\c`, which is what I would expect if both `head` and `tail` received the same input stream. – chepner May 20 '13 at 20:10
  • @chepner: What version of bash are you running? I am getting `a` and `b`. – choroba May 20 '13 at 20:16
  • 1
    Mea culpa. I've been testing with `zsh`, which raises its own set of (off-topic) questions :) – chepner May 20 '13 at 20:17
  • Wow, I would never thought about it. But it works! Thanks a lot! – Bouncner May 21 '13 at 01:17
  • Maybe an interesting observation: using zsh the output is apparently concurrent (alternating lines from tail and head), while it's not on my bash. – Bouncner May 21 '13 at 01:19
  • 1
    Oh gosh. No it does not work. To see how concurrent the shells are, I created a file with 1M lines (75MB). Now the command does not work as expected anymore (tail emits lines around 15k). Does the pipe gets closed to early? Any ideas? – Bouncner May 21 '13 at 01:22
  • @Bouncner: I do not understand it. If I replace `head` with `sed -n 1,10p` or `tac | tail | tac`, it works... :-O – choroba May 21 '13 at 07:04
  • 1
    See http://stackoverflow.com/q/16664257/1030675 for a follow-up. – choroba May 21 '13 at 07:18