Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About the usage of linux command "xargs"

Tags:

linux

shell

I have some file like

love.txt   loveyou.txt  

in directory useful; I want to copy this file to directory /tmp.

I use this command:

find ./useful/ -name "love*" | xargs cp /tmp/ 

but is doesn't work, just says:

cp: target `./useful/loveyou.txt' is not a directory 

when I use this command:

 find ./useful/ -name "love*" | xargs -i cp {} /tmp/ 

it works fine,

I want to know why the second works, and more about the usage of -i cp {}.

like image 541
BlackMamba Avatar asked Aug 07 '13 13:08

BlackMamba


People also ask

What is xargs command used for?

The xargs command builds and executes commands provided through the standard input. It takes the input and converts it into a command argument for another command. This feature is particularly useful in file management, where xargs is used in combination with rm , cp , mkdir , and other similar commands.

Why xargs is used in Linux?

The xargs command is used in a UNIX shell to convert input from standard input into arguments to a command. In other words, through the use of xargs the output of a command is used as the input of another command.

What is the default command used by xargs?

xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines, and executes the command (default is echo) one or more times with any initial-arguments followed by items read from standard input.

What does {} mean in xargs?

{} is a kind of placeholder for the output text we get from the previous command in the pipe.


2 Answers

xargs puts the words coming from the standard input to the end of the argument list of the given command. The first form therefore creates

cp /tmp/ ./useful/love.txt ./useful/loveyou.txt 

Which does not work, because there are more than 2 arguments and the last one is not a directory.

The -i option tells xargs to process one file at a time, though, replacing {} with its name, so it is equivalent to

cp ./useful/love.txt    /tmp/ cp ./useful/loveyou.txt /tmp/ 

Which clearly works well.

like image 142
choroba Avatar answered Sep 16 '22 16:09

choroba


When using the xargs -i command, {} is substituted with each element you find. So, in your case, for both "loveyou.txt" and "love.txt", the following command will be run:

cp ./useful/loveyou.txt /tmp/ cp ./useful/love.txt /tmp/ 

if you omit the {}, all the elements you find will automatically be inserted at the end of the command, so, you will execute the nonsensical command:

cp /tmp/ ./useful/loveyou.txt ./useful/love.txt 
like image 37
Erik A. Brandstadmoen Avatar answered Sep 17 '22 16:09

Erik A. Brandstadmoen