I am in trouble with xargs
and pipe
commands. Here is one example =
echo 'a' | xargs mkdir
This command creates a directory which name is a
. So I can understand that this commmand is equivalent to mkdir a
But why doesn't this command work = echo 'a' | mkdir
?
I read that pipe
command transfer left command's output as a input to right one , when | xargs
command transfers left command's output as a argument to right one.
1-What are differences between input and argument ?
2-echo 'a' | mkdir
why doesn't this command work and what is equivalent of this command ?
Thank you...
2 Answers 2
Simple answer
The arguments are an input.
Longer answer
There are also other types of input.
In your example echo 'a' | mkdir
you are expecting mkdir
to read its standard input. However mkdir
is not written to do this.
What you are calling input is standard-input (stdin
). And output is standard-out (stdout
). There is all standard-error (stderr
). And an exit code.
Even longer answer -- so what is the difference?
The arguments must be available before the program is started. It is typically: short; contains options, filenames, and short text.
Standard-in can be written to as the program is running; data can be sent to it, that did not exist when the program was started; It is not guaranteed that you can read it out of order (so read it sequentially); It can be of arbitrary length; There is only one standard-in per process, if you need more send file-names as arguments;
How to do echo 'a' | xargs mkdir
without xargs
mkdir "$(echo 'a')"
The $()
means run the contained command, then replace the $()
and its content with the standard-out of that command.
I was confused about this too, for a very long time. I'll take a slightly may be simpler example (I am by far no bash expert):
wc "test"
wc <<< "test" (same as: echo "test" | wc)
The result of these two are very different. The first one tries to read a file test
, the second one shows 1 1 5
.
The issue here is that wc "test"
gets the argument "test"
as input, while wc <<< "test"
takes stdin.
So when you issue echo 'a' | xargs mkdir
(xargs stands for: execute as an argument), you are passing an argument to mkdir
; it's like doing: mkdir a
.
On the other hand, when you issue echo 'a' | mkdir
(simpler would be : mkdir <<< 'a'
), you pass a
as stdin.
mkdir
treats these things very differently, thus the result you see.