5

I am executing command

ls > a.txt | sort > b.txt

This command is doing the below things :

  1. executing ls

  2. sorting it

  3. creating a.txt and storing sorted output to a.txt

  4. creating b.txt , but its empty.

Can anyone explain this ?

I am implementing my own shell for which I need to understand this behavior & simulate it.

  • Tried your line and worked for me. b.txt is not empty. – AndreiR Aug 10 '15 at 16:52
  • 1
    Um, no, that's not what it's doing. It's running "ls", sending that output to the file "a.txt" instead of to the pipe, which is now receiving nothing. That nothing is then being dutifully sorted and written to b.txt. – Lee Daniel Crocker Aug 10 '15 at 21:35
  • @AndreiR are you sure? – Alec Teal Aug 10 '15 at 23:30
  • @AlecTeal sure. Tried more than once. However Im using zsh and I dont know if it is related or not. – AndreiR Aug 10 '15 at 23:52
  • 1
    @AndreiR zsh is "smarter" in some ways. foo > a.txt > b.txt, for example, will send the output to both these files. – muru Aug 11 '15 at 3:18
14

The | will take the output of the command on the left and give it to the input of the command on the right. The > operator will take the output of the command and put it into a file. That means, in your example, by the time it gets to the | there is no output left; it's all gone into a.txt. So the sort on the right operates on an empty string and saves that to b.txt

What you would probably like is to use the tee command which will both write to a file and stdout like

ls | tee a.txt | sort > b.txt

Though I'm really curious what you're trying to do, since ls can/will sort things for you as well.

|improve this answer|||||
  • it is not doing this .. it is storing sorted ls output to a.txt and creating b.txt , but its empty. i am working on bash shell ! – KrunalParmar Aug 10 '15 at 16:57
  • @KrunalParmar that's what I said though, right? It stores the output to a.txt then has nothing left to pass through the pipe to sort. So that sorts an empty list and writes that to b.txt. Or did you mean the example with tee didn't work either? – Eric Renouf Aug 10 '15 at 17:01
  • but i am expecting output of ls to be stored in a.txt and , as you said nothing left for input to sort.. i am expecting that output only. but it is passing output of ls to sort and then storing it to a.txt...so my question is , why it is sorting and then saving to a.txt ?? i am expecting ls output in a.txt . but it is storing sorted output to a.txt... – KrunalParmar Aug 10 '15 at 17:11
  • 2
    You know ls sorts its output most of the time unless you tell it not to right? Try doing ls -f instead of just ls and see if you get the expected results – Eric Renouf Aug 10 '15 at 17:13
3

ls > a.txt | sort > b.txt

You are executing ls. Then you are redirecting only the STDOUT of the ls command into a.txt. Then you are trying to also PIPE STDOUT to the STDIN of the sort command.

Because STDOUT is being redirected into the file a.txt, there is nothing in the STDIN of the sort command to be sorted into b.txt, which is why the file is empty.

There are a couple of ways you could end up with the contents you expect in the b.txt file:

ls | sort > b.txt

or

ls > a.txt ; cat a.txt | sort > b.txt

Both require actually having data in STDOUT on the left of the PIPE to be passed to STDIN on the right of the PIPE.

|improve this answer|||||
  • 3
    cat a.txt | sort > b.txt is a Useless use of cat (UUOC); just do sort a.txt > b.txt. – Scott Aug 10 '15 at 20:29
  • Agreed, unless OP has a reason for having both the a.txt and b.txt files. – Tim Kennedy Aug 11 '15 at 17:56
1

Similar to what Tim and Eric say, when you use > to redirect the STDOUT to a file, nothing is left over for the | to pipe into sort. Instead, you can use tee which does 2 things at the same time:

  • Directs STDIN to a file
  • Directs STDIN to STDOUT

This has the result of both saving the STDIN (your ls command) to a file, and continuing it out to STDOUT to be used in the sort command. Here is the modified command that you are using:

ls | tee a.txt | sort > b.txt
|improve this answer|||||
  • 6
    Welcome to Unix & Linux (but I see that you are a Stack Exchange veteran).  "Similar to what Tim and Eric say"?  Your post is exactly what Eric said (in slightly different, slightly more verbose words).  Please strive to make answers add substantive new aspects not found in any existing answers.  Please don’t post an answer unless you actually have something new to contribute. – Scott Aug 10 '15 at 20:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.