2

I don't quite understand pipes in Linux command line.

I noticed that:

ll - R | grep *.pdf

will list files ending with .pdf

But

locate *.pdf | du -h

will not calculate the size of files ending with .pdf. Rather it will list the size of files in the current directory.

What is going wrong here?

What I have in mind is the output of the first command is the input of the next.

2 Answers 2

7

Pipes work by sending one program's output to another program's input. This means that the program receiving the output of the other has to be able to read from STDIN (standard streams).

In this case, grep is able to read the output of ll because it is designed that way. du expects a command line argument pointing to the directory it should run in (if a directory isn't given, it will default to the current working directory ./).

As for seeing the sizes of the .pdf files, if all the files are in a directory, you can run du -h -d1 /path/to/pdf/dir or locate *.pdf | xargs | du -h. If they are in different directories, you will want to use -exec and find together (another user will probably give you a hand with this, I'm not quite sure how to do it).

4
  • By the way, can you give me some example commands that are designed to read from STDIN Commented Dec 13, 2011 at 6:59
  • 3
    Instead of du -h -d1 /path/to/pdf/dir, it is also possible to use locate *.pdf | xargs | du -h
    – bbaja42
    Commented Dec 13, 2011 at 8:46
  • @bbaja42 thanks, I'll add that to the post.
    – nopcorn
    Commented Dec 13, 2011 at 21:18
  • @bbaja42 There's one too many | characters there. try locate *.pdf | xargs du -h instead (i.e. no | between xargs and du). Also, if any of the filenames contain spaces or newlines, it's safer to use locate -0 *.pdf | xargs -0 -r du -h (assuming your locate is actually mlocate or some other locate that has the -0 option). Finally, this won't work correctly if there any .pdf files in the current directory because the shell will expand the glob before passing it to locate - use locate -0 .pdf instead.
    – cas
    Commented Mar 15, 2016 at 10:42
2

What I have in mind is the output of the first command is the input of the next.

That is correct. However, in your two examples, the difference is that grep acts on its input whereas du does not. Piping works as expected only if the first command gives something to the standard output and the second takes something from the standard input, in which case thes two flows will be connected through a "pipe". You can find out if this is possible by looking for "standard input" and "standard output" in the man pages of the commands.

2
  • I do not quite understand why grep acts on its input whereas du does not. How can judge that grep can while du can not. Or given another program, how can I determine whether it can or not act on its input? Commented Dec 13, 2011 at 6:57
  • 1
    Both man grep and grep --help tell you in the first lines that standard input is accepted by this command. This should be the case for any command accepting STDIN.
    – Dalker
    Commented Dec 13, 2011 at 7:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .