Misplaced Pages

Xargs: Difference between revisions

Article snapshot taken from Wikipedia with creative commons attribution-sharealike license. Give it a read and then ask your questions in the chat. We can research this topic together.
Browse history interactively← Previous editNext edit →Content deleted Content addedVisualWikitext
Revision as of 22:46, 13 February 2012 edit209.51.180.226 (talk) If you short an article by more than 50% please discuss before editing← Previous edit Revision as of 20:31, 16 February 2012 edit undoTenPoundHammer (talk | contribs)Autopatrolled, Extended confirmed users, Page movers, Pending changes reviewers, Rollbackers278,939 edits prodNext edit →
Line 1: Line 1:
{{notability}}
{{multiple issues|cleanup=September 2011|lead too long=September 2011}}
{{Proposed deletion/dated
{{NOT|date=September 2011}}
|concern = Notable? Not sure
|timestamp = 20120216203104
}}
{{lowercase|title=xargs}} {{lowercase|title=xargs}}
'''xargs''' is a command on ] and most ] operating systems used to build and execute command lines from ]. Under the ] before version 2.6.23, arbitrarily long lists of parameters could not be passed to a command,<ref></ref> so xargs breaks the list of arguments into sublists small enough to be acceptable. '''xargs''' is a command on ] and most ] operating systems used to build and execute command lines from ]. Under the ] before version 2.6.23, arbitrarily long lists of parameters could not be passed to a command,<ref></ref> so xargs breaks the list of arguments into sublists small enough to be acceptable.

Revision as of 20:31, 16 February 2012

The topic of this article may not meet Misplaced Pages's general notability guideline. Please help to demonstrate the notability of the topic by citing reliable secondary sources that are independent of the topic and provide significant coverage of it beyond a mere trivial mention. If notability cannot be shown, the article is likely to be merged, redirected, or deleted.
Find sources: "Xargs" – news · newspapers · books · scholar · JSTOR (Learn how and when to remove this message)
This article may have been previously nominated for deletion: Misplaced Pages:Articles for deletion/Xargs exists.
It is proposed that this article be deleted because of the following concern:

Notable? Not sure

If you can address this concern by improving, copyediting, sourcing, renaming, or merging the page, please edit this page and do so. You may remove this message if you improve the article or otherwise object to deletion for any reason. Although not required, you are encouraged to explain why you object to the deletion, either in your edit summary or on the talk page. If this template is removed, do not replace it.

This message has remained in place for seven days, so the article may be deleted without further notice.

If you created the article, please don't be offended. Instead, consider improving the article so that it is acceptable according to the deletion policy.
Find sources: "Xargs" – news · newspapers · books · scholar · JSTOR
PRODExpired+%5B%5BWP%3APROD%7CPROD%5D%5D%2C+concern+was%3A+Notable%3F+Not+sureExpired ], concern was: Notable? Not sure
Nominator: Please consider notifying the author/project: {{subst:proposed deletion notify|Xargs|concern=Notable? Not sure}} ~~~~
Timestamp: 20120216203104 20:31, 16 February 2012 (UTC)
Administrators: delete

xargs is a command on Unix and most Unix-like operating systems used to build and execute command lines from standard input. Under the Linux kernel before version 2.6.23, arbitrarily long lists of parameters could not be passed to a command, so xargs breaks the list of arguments into sublists small enough to be acceptable.

For example, commands like:

 rm /path/*

or

 rm `find /path -type f`

will fail with an error message of "Argument list too long" if there are too many files in /path.

However the version below (functionally equivalent to rm `find /path -type f`) will not fail:

 find /path -type f -print0 | xargs -0 rm

In the above example, the find utility feeds the input of xargs with a long list of file names. xargs then splits this list into sublists and calls rm once for every sublist.

The previous example is more efficient than this functionally equivalent version which calls rm once for every single file:

 find /path -type f -exec rm '{}' \;

Note however that with modern versions of find, the following variant does the same thing as the xargs version:

 find /path -type f -exec rm '{}' +

xargs often covers the same functionality as the backquote (`) feature of many shells, but is more flexible and often also safer, especially if there are blanks or special characters in the input. It is a good companion for commands that output long lists of files like find, locate and grep, but only if you use -0, since xargs without -0 deals badly with file names containing ', " and space. GNU Parallel is the perfect companion to find, locate and grep if file names may contain ', " and space (newline still requires -0).

Examples

 find . -name "*.foo" | xargs grep bar

The above is equivalent to:

 grep bar `find . -name "*.foo"`

Note that the above command uses backticks (`), not single quotes ('). It searches all files in the current directory and its subdirectories which end in .foo for occurrences of the string bar. These commands will not work as expected if there are whitespace characters, including newlines, in the filenames. In order to avoid this limitation one may use:

 find . -name "*.foo" -print0 | xargs -0 grep bar

The above command uses GNU specific extensions to find and xargs to separate filenames using the null character;


 find . -name "*.foo" -print0 | xargs -0 -t -r vi

The above command is similar to the former one, but launches the vi editor for each of the files. The -t prints the command to stderr before issuing it. The -r is a GNU extension that tells xargs not to run the command if no input was received.


 find . -name "*.foo" -print0 | xargs -0 -I {} mv {} /tmp/trash

The above command uses -I to tell xargs to replace {} with the argument list. Note that not all versions of xargs supports the {} syntax. In those cases you may specify a string after -I that will be replaced, e.g.


 find . -name "*.foo" -print0 | xargs -0 -I xxx mv xxx /tmp/trash

The above command uses string xxx instead of {} as the argument list marker.


 find . -maxdepth 1 -type f -name "*.ogg" -print0 | xargs -0 -r cp -v -p --target-directory=/home/media

The command above does the same as:

 cp -v -p *.ogg /home/media

however, the former command which uses find/xargs/cp is more resource efficient and will not halt with an error if the number of files is too large for the cp command to handle. Another way to do it (choosing where to put your arguments) is:

 find . -maxdepth 1 -type f -name "*.ogg" -print0 | xargs -0 -I MYFILES cp MYFILES /home/media

The -I in the above command tells xargs what replacement string you want to use (otherwise it adds the arguments to the end of the command). You can also use -L to limit the number of arguments. If you do that, the command will be run repeatedly until it is out of arguments. Thus, -L1 runs the command once for each argument (needed for tools like tar and such).

The separator problem

Many UNIX utilities are line oriented. These may work with xargs as long as the lines do not contain ', " or space. Some of the UNIX utilities can use NULL as record separator (e.g. perl (requires -0 and \0 instead of \n), locate (requires using -0), find (requires using -print0), grep (requires -z or -Z), sort (requires using -z)). Using -0 for xargs deals with the problem, but many UNIX utilities cannot use NULL as separator (e.g. head, tail, ls, echo, sed, tar -v, wc, which).

But often people forget this and assume xargs is also line oriented.

The separator problem is illustrated here:

 touch important_file
 touch 'not important_file'
 find -name not\* | tail | xargs rm
 mkdir -p '12" records'
 find \! -name . -type d | tail | xargs rmdir

Running the above will cause important_file to be removed and will remove neither the directory called 12" records, nor the file called not important_file.

The proper fix is to use find -print0, but tail (and other tools) do not support NULL terminated strings:

 touch important_file
 touch 'not important_file'
 find -name not\* -print0 | xargs -0 rm
 mkdir -p '12" records'
 find \! -name . -print0 | xargs -0 rmdir

When using the syntax find -print0, entries are separated by a null character instead of a end-of-line. This is equivalent to the more verbose command:

 find -name not\* | tr \\n \\0 | xargs -0 rm

GNU Parallel is an alternative to xargs that is designed to have the same options, but be line oriented. Thus, using GNU Parallel instead, the above would work as expected.

For Unix environments where xargs does not support the -0 option (e.g. Solaris), the following can not be used as it does not deal with ' and " (GNU Parallel would work on Solaris, though):

 find -name not\* | sed 's/ /\\ /g' | xargs rm

References

  1. GNU Core Utilities FAQ
  2. Google search showing people forgetting -0
  3. http://www.gnu.org/software/parallel/

External links

Manual pages

Unix command-line interface programs and shell builtins
File system
Processes
User environment
Text processing
Shell builtins
Searching
Documentation
Software development
Miscellaneous
Categories: