2
cal April 2012 | cat > t | cat < t | more

Why does it showing nothing? Why isn't it showing

     April 2012       
Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  
29 30  
12
  • | connects stdout (1) of the first process with stdin (0) of the second. After redirecting the output to a file, there is no stdout left, so there's nothing to pipe. Also, cat | cat < file does not really make sense, it gets two inputs to stdin Commented Apr 5, 2012 at 13:43
  • @knittl So do you mean cat < t is not executed at all? Commented Apr 5, 2012 at 13:45
  • so, is there any other way to do this? Commented Apr 5, 2012 at 13:45
  • @PavanManjunath typing cat < t (only) gives the calender perfectly Commented Apr 5, 2012 at 13:46
  • 1
    @knittl agreed; I sacrificed technical precision for conceptual clarity. :) I suppose describing it in terms of fd0 would have helped understand the why of the conflicting STDINs. It's actually an interesting problem: if you run the second cat using strace cal April 2012 | cat > t | strace cat < t, you'll see that in fact it reads the cal text from fd0, and writes the cal text to fd1. Bash must be shuffling something around. Commented Apr 5, 2012 at 14:31

3 Answers 3

5

| (anonymous pipe) connects stdout (1) of the first process with stdin (0) of the second. After redirecting the output to a file, there is no stdout left, so there's nothing to pipe. Also, cat | cat < file does not really make sense, it gets two inputs connected to stdin (at least with bash, redirection comes later and "wins": echo uiae | cat <somefile will output the content of somefile)

If you want to display output of a command and, at the same time, write it to the file, use the tee binary. It writes to a file, but still writes to stdout

cal April 2012 | tee t | more
cat t # content of the above `cal` command
Sign up to request clarification or add additional context in comments.

1 Comment

Can you name a command which reads from file and give stdout? (like tee writes to file and stdout)
1

Because that first cat > t sends all its output to a file called t, leaving no more for the pipeline.

If your intent is to send it to a file and through more to the terminal, just use:

cal April 2012 | tee t | more

This | cat < t construct is very strange and I'm not even sure if it would work. It's trying to connect two totally different things to the standard input of cat and certainly unnecessary.

Comments

0

this works for me if there's no existing file named t in the current directory. I'm using bash on Ubuntu Oneiric.

$ cal April 2012 | cat > t | cat < t | more
 April 2012       
 Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
 15 16 17 18 19 20 21  
 22 23 24 25 26 27 28  
 29 30
$ cal April 2012 | cat > t | cat < t | more
$ rm t
$ cal April 2012 | cat > t | cat < t | more
 April 2012       
 Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
 15 16 17 18 19 20 21  
 22 23 24 25 26 27 28  
 29 30

4 Comments

Should not work (and does not work here – debian squeeze. I can test in ubuntu later)
If it's trick works for you, can you explain why it happens like this?
hmm. if I run cal April 2012 | cat > t | cat < t | more over and over, occasionally I get output and occasionally I don't. GNU bash, version 4.2.10(1)-release (i686-pc-linux-gnu)
@orzechowskid I got the same issue. It sometimes works for me, sometimes not! Totally strange!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.