Why don’t all commands work with pipe?

Asked

Viewed 235 times

4

I’m intrigued by the fact that kill and some other commands do not work with pipe. For example, I tried cat /tmp/server.pid | kill -9 and it didn’t work. Searching some forums in English I found the solution: kill -9 $(cat /tmp/server.pid). All right, problem solved.

However the doubt remained. As well as the kill, there are other commands that do not work with pipe use, such as rm and ls. I read somewhere that pipe works only with commands waiting for input from stdin. But taking into account that stdin corresponds to the keyboard, all commands do not accept input coming from stdin? It seems to be a very basic thing... but I am confused about this.

2 answers

3

Take this way, let’s use the Kill command as the first example:

Let’s say the output of the "cat /tmp/server.pid" command is something like "3193". As you did the first time, your command with pipe + Kill would look something like: "3193 Kill -9"; but we know that this will not work because we have to execute the command "Kill -9" followed by a parameter, in case the pid of the process we want to close; so the correct thing would be to turn this parameter into a variable, which is not possible with the use of the pipe, because it serves to "concatenate" and/or redirect commands.

How you use the pipe depends solely on how you organize your commands, see:

"As a beginner in Linux I realized the relevance of pipe to make shell commands more practical and easier to write and therefore decided to share my experience on this command.

Pipe is one of the ways that Linux can use for inter-process communication. In a simple way we could say that the pipe is nothing more than the chain of processes. At first glance the pipe may not even attract attention from beginners, but it is a very powerful tool. This process chaining can be activated by the user via the "|" command. Now let’s demonstrate in the example below the potentiality of this tool:

$ ls | grep b | Sort -r | tee file.out | wc -l

  • The "ls" command, as we well know, lists the contents of the directory, but due to the pipe it does not send the result to the screen command "grep b".
  • The "grep b" command in turn filters the names of files containing the letter "b". Due to the second pipe the output of "grep b" command is sent to "Sort -r", which sorts the names in rising order.
  • The output of "Sort -r " is then passed to the command "tee", which divides the data in two, as if it were a connection in t, causing the information processed by the "Sort -r" command are written in the "archive.out".
  • Then the command "toilet -l" counts the lines of the file "file.out". So we get as result the amount of files containing the letter "b" printed on screen and the name of those files in ".out file".

(...)

Reference: Using the pipe

2


As a matter of fact, no programme is obliged to process data from stdin (that is, via keyboard or pipe). A program can be built to handle data from a predefined file, read a port, or simply do nothing.

If you want, it can read data from stdin. Similarly, if you want, it can read data from the command line that was used to start it, which is what the kill ago.

The reason most Unix/Linux commands handle stdin is because of Unix philosophy:

"Write programs that do one thing and do it well. Write programs work together. Write programs to handle text chains, because this is a universal interface."

It is a philosophy that stimulates to chain programs as a sequence of filters, to be able to give varied treatment to arbitrary sets of data.

But not all Unix/Linux commands have reasons to follow it. This has to do with the type of action the command performs, and whether it has filter behavior or not. This answer (in English) provides more details.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.