|
Softpanorama |
May the source be with you, but remember the KISS principle ;-)
Softpanorama Search
|
| News | Books | See also | Recommended Links | Examples |
Additional Examples |
|
| find | grep | Pipes | AWK | Perl | Regex | |
| sort | uniq | cut | tee | History | Humor | Etc |
The xargs utility is one of the most useful and the most underappreciated utilities in Unix piping toolbox. It is often used with find command as it is more flexible then build in option -exec.
Xargs constructs an argument list for an arbitrary Unix command using standard input and executes this command. xargs [options] [command]
The xargs command creates an argument list for command from standard input. It is typically used with a pipe getting its input from commands like ls and find The latter is probably the most common source of xargs input and is covered in examples below.
One of the most common xargs applications in pipes is to execute a command once for each piped record:
find . -name '*050106*' print | xargs -n2 grep 'From: Ralph'
cat iplist | xargs -n1 nmap -sV
The find command searches the entire directory structure for filenames that contain 050106 . The xargs command executes grep command for each two argument (so that filename was visible). In the second example cat command supplies the list of IPs for map to scan.
In many Unix shells there is a limit to the number of arguments allowed on a single command line. This is often a problem when you analyze spam blocked by a spam filter. Here xargs can help: if the argument list read by xargs is larger than the maximum allowed by the shell, xargs will bundle the arguments into smaller groups and execute command separately for each argument bundle.
If no command is specified, xargs works similar to the echo command and prints the argument list to standard output.
| Option | Description |
| -n# | Execute command once for every # argument. For
example, |
| -l# | Execute command once for every # lines of input. For
example, |
| -i | Normally xargs places input arguments at the end of
command. Used with the |
| -t | Echo each command before executing. Nice for debugging |
| -p | Prompts the user before executing each command. Useful for debugging. |
xargs lint -a < cfiles
If the cfiles file contains the following text:
main.c readit.c gettoken.c putobj.c
the xargs command constructs and runs the following command:
lint -a main.c readit.c gettoken.c putobj.c
If the cfiles file contains more file names than fit on a single shell command line (up to LINE_MAX), the xargs command runs the lint command with the file names that fit. It then constructs and runs another lint command using the remaining file names. Depending on the names listed in the cfiles file, the commands might look like the following:
lint -a main.c readit.c gettoken.c . . . lint -a getisx.c getprp.c getpid.c . . . lint -a fltadd.c fltmult.c fltdiv.c . . .
This command sequence is not quite the same as running the lint command once with all the file names. The lint command checks cross-references between files. However, in this example, it cannot check between the main.c and the fltadd.c files, or between any two files listed on separate command lines.
For this reason you may want to run the command only if all the file
names fit on one line. To specify this to the xargs command use
the -x flag by entering:
xargs -x
lint -a <cfiles
If all the file names in the cfiles file do not fit on one
command line, the xargs command displays an error message.
diff starting chap1 diff concepts chap2 diff writing chap3
The -t
flag causes the xargs command to display each
command before running it, so you can see what is happening. The
<<EOF and EOF pattern-matching characters define a
here document, which uses the text entered before the end
line as standard input for the xargs command.
mv chap1 chap1.old mv chap2 chap2.old mv chap3 chap3.old
Something similar to the following displays:
ar r lib.a chap1 ?... ar r lib.a chap2 ?... ar r lib.a chap3 ?...
ls | xargs -n6 | xargs -I{} echo {} - some files in the directory
If the current directory contains files chap1 through chap10, the output constructed will be the following:
chap1 chap2 chap3 chap4 chap5 chap6 - some files in the directory chap7 chap8 chap9 chap10 - some file in the directory
Typically arguments are lists of filenames passed to xargs via a pipe. Please compare:
$ ls 050106*
$ ls 050106* | xargs -n2 grep "From: Ralph"
In the first example list of files that starts with 050106 is printed. In
the second for each two such files grep is executed.
Oracle Tips UNIX find and catChange permissions on all regular files in a directory subtree to mode 444, and permissions on all directories to 555:
find-type f -print | xargs chmod 444 $ ls * | xargs -n2 head -10 line 1 of f1 line 2 of f1 line 3 of f1ls * } xarg -n1 wc -1(date +%D ; du -s ~) | xargs >> logls *.txt | xargs -i basename \{\} .ascii \ | xargs -i mv \{\}.ascii \{\}.ask(Note that the backslash usage)
Another example. Let's "cat" the Contents of Files Listed in a File, in That Order.So there are 3 files here "file_of_files" which contains the name of other files. In this case "file1" and "file2". And the contents of file1" and "file2" is shown above.$ cat file_of_files
file1
file2
$ cat file1
This is the data in file1
$ cat file 2
This is the data in file2
$ cat file_of_files | xargs cat
This is the data in file1
This is the data in file2
What if you want to find a string in all finds in the current directory and below. Well the following script will do it.
Another quite nice thing, used for updating CVS/Root files on a Zaurus:#!/bin/sh
SrchStr=$1
shift
for i in $*; do
find . -name "$i" -type f -print | xargs egrep -n "$SrchStr"/dev/null
donefind . -name Root | xargs cp newRootJust copies the contents of newRoot into every Root file. I think this works too:
find . -name Root | xargs 'echo user@machine.dom:/dir/root >'
as long as the quote are used to avoid the initial interpretation of the >.
These pieces of randomness will look for all .sh files in PWD and print the 41st line of each - don't ask me why I wanted to know. Thanks to Brian R for these.
for f in *.sh; do sed -n '41p' $f; doneor
ls *.sh | xargs -l sed -n '41p' Remove all the files in otherdir that exist in thisdir.ls -1d ./* | xargs -i rm otherdir/{}
Locate Oracle files that contain certain strings - This is one of the most common shell command for finding all files that contain a specified string. For example, assume that you are trying to locate a script that queries the v$process table. You can issue the following command, and UNIX will search all subdirectories, looking in all files for the v$process table.
root> find . -print|xargs grep v\$process
./TX_RBS.sql: v$process p,
./UNIX_WHO.sql:from v$session a, v$process b
./session.sql:from v$session b, v$process a
broadband » Forums » All things UNIX » Little Known Tips and Tricks...To follow on to Steve's xargs madness, let's say you've got some daemon process that is just running away. It's spawning more and more processes and "service blah stop" is not doing anything for you. Here's a cute way to kill all of those processes with the "big hammer":
ps -auxwww | grep "daemonname" | awk '{print $2}' | xargs kill -9
Tips and tricks for Mandrake Linux
If you edit files on linux, chances are you'll end up with a lot of those backup files with names ending with
~, and removing them one by one is a pain.
Luckily, with a simple command you can get them all, and recursively. Simply go into the top of the directory tree you want to clean (be carefull, these commands are recursive, they will run through the subdirectories), and type
find ./ -name '*~' | xargs rm
Some explanations:
- the command
find ./ -name '*~'will look for all files ending with~in the local directory and its subdirectories,- the sign
|is a 'pipe' that makes the outout of the previous command becoming the input of the next one,xargsreads the arguments on the standard input and applies it to the following commandrmdeletes whatever file you want.
Print or Query Before Executing Commands
- Used with the
-t option, xargs echoes each command before executing. For example, the following command moves all files in dir1 into the directory dir2.$ ls dir1 | xargs -i -t mv dir1/\{\} dir2/\{\} mv dir1/f1 dir2/f1 mv dir1/f2 dir2/f2 mv dir1/f3 dir2/f3- Used with the
-p option, xargs prompts the user before executing each command. For example,$ ls dir1 | xargs -i -p mv dir1/\{\} dir2/\{\} mv dir1/f1 dir2/f1 ?...y mv dir1/f2 dir2/f2 ?...n mv dir1/f3 dir2/f3 ?...yFiles f1 and f3 were moved but file f2 was not.
- Use the query (-p) option, to choose which files in the current directory should be compressed.
$ ls | xargs -n1 -p compress compress largef1 ?...y compress largef2 ?...y compress smallf1 ?...n compress smallf2 ?...n
|
|||||||
This command:
rm `find tmp -maxdepth 1 -name '*.mp3'`is intended to remove all tmp/*.mp3 files (and ignore any subdirectories), but can fail with an "Argument list too long" message. This exact equivalent:find tmp -maxdepth 1 -name '*.mp3' -maxdepth 1 | xargs rmdoes exactly the same thing but will avoid the problem by batching arguments up. More modern kernels (since 2.6.23) shouldn't have this issue, but it's wise to make your scripts as portable as possible; and the xargs version is also easier on the eye.You can also manually batch arguments if needed, using the -n option.
find tmp -maxdepth 1 -name '*.mp3' -maxdepth 1 | xargs -n1 rmwill pass one argument at a time to rm. This is also useful if you're using the -p option as you can confirm one file at a time rather than all at once.Filenames containing whitespace can also cause problems; xargs and find can deal with this, using GNU extensions to both to break on the null character rather than on whitespace:
find tmp -maxdepth 1 -name *.mp3 -print0 | xargs -0 rmYou must use these options either on both find and xargs or on neither, or you'll get odd results.Another common use of xargs with find is to combine it with grep. For example,
find . -name '*.pl' | xargs grep -L '^use strict'will search all the *.pl files in the current directory and subdirectories, and print the names of any that don't have a line starting with 'use strict'. Enforce good practice in your scripting!
July 07, 2007 | esofthub.blogspot.com
Find how many directories are in a path (counts current directory)
# find . -type d -exec basename {} \; | wc -l
53
Find how many files are in a path
# find . -type f -exec basename {} \; | wc -l
120
... ... ...Find files that were modified 7 days ago and archive
# find . -type f -mtime 7 | xargs tar -cvf `date '+%d%m%Y'_archive.tar`
Find files that were modified more than 7 days ago and archive
# find . -type f -mtime +7 | xargs tar -cvf `date '+%d%m%Y'_archive.tar`
Find files that were modified less than 7 days ago and archive
# find . -type f -mtime -7 | xargs tar -cvf `date '+%d%m%Y'_archive.tar`
Find files that were modified more than 7 days ago but less than 14 days ago and archive
# find . -type f -mtime +7 -mtime -14 | xargs tar -cvf `date '+%d%m%Y'_archive.tar`
Find files in two different directories having the "test" string and list them
# find esofthub esoft -name "*test*" -type f -ls
Find files and directories newer than CompareFile
# find . -newer CompareFile -print
Find files and directories but don't traverse a particular directory
# find . -name RAID -prune -o -print
Find all the files in the current directory
# find * -type f -print -o -type d -prune
Find files associated with an inode
# find . -inum 968746 -print
# find . -inum 968746 -exec ls -l {} \;
Find an inode and remove
# find . -inum 968746 -exec rm -i {} \;Comment for the blog entry
ux-admin said...Avoid using "-exec {}", as it will fork a child process for every file, wasting memory and CPU in the process. Use `xargs`, which will cleverly fit as many arguments as possible to feed to a command, and split up the number of arguments into chunks as necessary:
find . -depth -name "blabla*" -type f | xargs rm -f
Also, be as precise as possible when searching for files, as this directly affects how long one has to wait for results to come back. Most of the stuff actually only manipulates the parser rather than what is actually being searched for, but even there, we can squeeze some performance gains, for example:
- use "-depth" when looking for ordinary files and symollic links, as "-depth" will show them before directories
- use "-depth -type f" when looking for ordinary file(s), as this speeds up the parsing and the search significantly:
find . -depth -type f -print | ...
- use "-mount" as the first argument when you know that you only want to search the current filesystem, and
- use "-local" when you want to filter out the results from remote filesystems.
Note that "-local" won't actually cause `find` not to search remote file systems -- this is one of the options that affects parsing of the results, not the actual process of locating files; for not spanning remote filesystems, use "-mount" instead:
find / -mount -depth \( -type f -o -type l \) -print ...
- Josh said...
- From the find(1) man page:
-exec command {} +
This variant of the -exec option runs the specified command on the selected files, but the command line is
built by appending each selected file name at the end; the total number of invocations of the command will
be much less than the number of matched files. The command line is built in much the same way that xargs
builds its command lines. Only one instance of â{}â is allowed within the command. The command is exeâ
cuted in the starting directory.- the recursive finds were useful
- " Josh said...
From the find(1) man page:
-exec command {} +
This variant of the -exec option runs the specified command on the selected files, but the command line is
built by appending each selected file name at the end; the total number of invocations of the command will
be much less than the number of matched files. The command line is built in much the same way that xargs
builds its command lines. Only one instance of â{}â is allowed within the command. The command is exeâ
cuted in the starting directory."
Apparently, "-exec" seems to be implementation specific, which is another good reason to avoid using it, since it means that performance factor will differ from implementation to implementation.
My point is, by using `xargs`, one assures that the script / command will remain behaving the same across different UNIX(R) and UNIX(R) like operating systems.
If you had to choose between convenience and portability+consistency, which one would you choose?
- instead of using
find ./ -name blah
I find it better to use the case-insentive form of -name, -iname:
find ./ -iname blah
- You have to be careful when you remove things.
You say remove files which name is core, but lacks the "-type f" option:
find . -name "core" -exec rm -f {} \;
The same for the example with directories named "junk". Your command would delete any type of files called junk (files, directories, links, pipes...)
I did not know about "-mount", I've always used "-xdev".
Another nice feature, at least in linux find, is the "-exec {} \+", which will fork only once.
Re:pushd and popd (and other tricks) (Score:2)
by Ramses0 (63476) on Wednesday March 10, @07:39PM (#8527252)My favorite "Nifty" was when I spent the time to learn about "xargs" (I pronounce it zargs), and brush up on "for" syntax.
ls | xargs -n 1 echo "ZZZ> "
Basically indents (prefixes) everything with a "ZZZ" string. Not really useful, right? But since it invokes the echo command (or whatever command you specify) $n times (where $n is the number of lines passed to it) this saves me from having to write a lot of crappy little shell scripts sometimes.
A more serious example is:
find -name \*.jsp | sed 's/^/http:\/\/127.0.0.1/server/g' | xargs -n 1 wget...will find all your jsp's, map them to your localhost webserver, and invoke a wget (fetch) on them. Viola, precompiled JSP's.
Another:
for f in `find -name \*.jsp` ; do echo "==> $f" >> out.txt ; grep "TODO" $f >> out.txt ; done...this searches JSP's for "TODO" lines and appends them all to a file with a header showing what file they came from (yeah, I know grep can do this, but it's an example. What if grep couldn't?)
...and finally... ( echo "These were the command line params"
echo "---------"
for f in $@ ; do
echo "Param: $f"
done
) | mail -s "List" you@you.com...the parenthesis let your build up lists of things (like interestingly formatted text) and it gets returned as a chunk, ready to be passed on to some other shell processing function.
Shell scripting has saved me a lot of time in my life, which I am grateful for.:^) [Dec 12, 2006] UNIX tips Learn 10 good UNIX usage habits by Michael Stutz
Use xargs outside of find
Use the
Listing 13. Example of the classic use of thexargstool as a filter for making good use of output culled from thefindcommand. The general precept is that afindrun provides a list of files that match some criteria. This list is passed on toxargs, which then runs some other useful command with that list of files as arguments, as in the following example:xargstoolfind some-file-criteria some-file-path | xargs some-command-that-needs-filename-argumentsHowever, do not think of
xargsas just a helper forfind; it is one of those underutilized tools that, when you get into the habit of using it, you want to try on everything, including the following uses.Passing a space-delimited list
In its simplest invocation,
xargsis like a filter that takes as input a list (with each member on a single line). The tool puts those members on a single space-delimited line:
Listing 14. Example of output from thexargstool~ $ xargs a b c Control-D $ a b cYou can send the output of any tool that outputs file names through
Listing 15. Example of using of thexargsto get a list of arguments for some other tool that takes file names as an argument, as in the following example:xargstool~/tmp $ ls -1 | xargs December_Report.pdf README a archive.tar mkdirhier.sh ~/tmp $ ls -1 | xargs file December_Report.pdf: PDF document, version 1.3 README: ASCII text a: directory archive.tar: POSIX tar archive mkdirhier.sh: Bourne shell script text executable ~/tmp $Thexargscommand is useful for more than passing file names. Use it any time you need to filter text into a single line:Listing 16. Example of good habit #7: Using the
xargstool to filter text into a single line
~/tmp $ ls -l | xargs -rw-r--r-- 7 joe joe 12043 Jan 27 20:36 December_Report.pdf -rw-r--r-- 1 \ root root 238 Dec 03 08:19 README drwxr-xr-x 38 joe joe 354082 Nov 02 \ 16:07 a -rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar -rwxr-xr-x 1 \ joe joe 3239 Sep 30 12:40 mkdirhier.sh ~/tmp $Be cautious usingxargsTechnically, a rare situation occurs in which you could get into trouble using
xargs. By default, the end-of-file string is an underscore (_); if that character is sent as a single input argument, everything after it is ignored. As a precaution against this, use the-eflag, which, without arguments, turns off the end-of-file string completely.[Jul 30, 2003] Unix Review Using the xargs Command Ed Schaefer
Many UNIX professionals think the xargs command, construct and execute argument lists, is only useful for processing long lists of files generated by the find command. While xargs dutifully serves this purpose, xargs has other uses. In this article, I describe xargs and the historical "Too many arguments" problem, and present eight xargs "one-liners":
Examining the "Too Many Arguments" Problem
- Find the unique owners of all the files in a directory.
- Echo each file to standard output as it deletes.
- Duplicate the current directory structure to another directory.
- Group the output of multiple UNIX commands on one line.
- Display to standard output the contents of a file one word per line.
- Prompt the user whether to remove each file individually.
- Concatenate the contents of the files whose names are contained in file into another file.
- Move all files from one directory to another directory, echoing each move to standard output as it happens.
In the early days of UNIX/xenix, it was easy to overflow the command-line buffer, causing a "Too many arguments" failure. Finding a large number of files and piping them to another command was enough to cause the failure. Executing the following command, from Unix Power Tools, first edition (O'Reilly & Associates):
pr -n 'find . -type f -mtime -1 -print'|lprwill potentially overflow the command line given enough files. This command provides a list of all the files edited today to pr, and pipes pr's output to the printer. We can solve this problem with xargs:find . -type f -mtime -1 -print|xargs pr -n |lpWith no options, xargs reads standard input, but only writes enough arguments to standard output as to not overflow the command-line buffer. Thus, if needed, xargs forces multiple executions of pr -n|lp.While xargs controls overflowing the command-line buffer, the command xargs services may overflow. I've witnessed the following mv command fail -- not the command-line buffer -- with an argument list too long error:
find ./ -type f -print | xargs -i mv -f {} ./newdirLimit the number of files sent to mv at a time by using the xargs -l option. (The xargs -i () syntax is explained later in the article). The following command sets a limit of 56 files at time, which mv receives:find ./ -type f -print | xargs -l56 -i mv -f {} ./newdirThe modern UNIX OS seems to have solved the problem of the find command overflowing the command-line buffer. However, using the find -exec command is still troublesome. It's better to do this:# remove all files with a txt extension find . -type f -name "*.txt" -print|xargs rmthan this:find . -type f -name "*.txt" -exec rm {} \; -printControlling the call to rm with xargs is more efficient than having the find command execute rm for each object found.xargs One-Liners
The find-xargs command combination is a powerful tool. The following example finds the unique owners of all the files in the /bin directory:
# all on one line find /bin -type f -follow | xargs ls -al | awk ' NF==9 { print $3 } '|sort -uIf /bin is a soft link, as it is with Solaris, the -follow option forces find to follow the link. The xargs command feeds the ls -al command, which pipes to awk. If the output of the ls -al command is 9 fields, print field 3 -- the file owner. Sorting the awk output and piping to the uniq command ensures unique owners.You can use xargs options to build extremely powerful commands. Expanding the xargs/rm example, let's assume the requirement exists to echo each file to standard output as it deletes:
find . -type f -name "*.txt" | xargs -i ksh -c "echo deleting {}; rm {}"The xargs -i option replaces instances of {} in a command (i.e., echo and rm are commands).Conversely, instead of using the -i option with {}, the xargs -I option replaces instances of a string. The above command can be written as:
find . -type f -name "*.txt" | xargs -I {} ksh -c "echo deleting {}; rm {}"The new, third edition of Unix Power Tools by Powers et al. provides an xargs "one-liner" that duplicates a directory tree. The following command creates in the usr/project directory, a copy of the current working directory structure:find . -type d -print|sed 's@^@/usr/project/@'|xargs mkdirThe /usr/project directory must exist. When executing, note the error:mkdir: Failed to make directory "/usr/project/"; File existswhich doesn't prevent the directory structure creation. Ignore it. To learn how the above command works, you can read more in Unix Power Tools, third edition, Chapter 9.17 (O'Reilly & Associates).In addition to serving the find command, xargs can be a slave to other commands. Suppose the requirement is to group the output of UNIX commands on one line. Executing:
logname; datedisplays the logname and date on two separate lines. Placing commands in parentheses and piping to xargs places the output of both commands on one line:(logname; date)|xargsExecuting the following command places all the file names in the current directory on one line, and redirects to file "file.ls":ls |xargs echo > file.lsUse the xargs number of arguments option, -n, to display the contents of "file.ls" to standard output, one name per line:cat file.ls|xargs -n1 # from Unix in a NutshellIn the current directory, use the xargs -p option to prompt the user to remove each file individually:ls|xargs -p -n1 rmWithout the -n option, the user is prompted to delete all the files in the current directory.Concatenate the contents of all the files whose names are contained in file:
xargs cat < file > file.contentsinto file.contents.Move all files from directory $1 to directory $2, and use the xargs -t option to echo each move as it happens:
ls $1 | xargs -I {} -t mv $1/{} $2/{}The xargs -I argument replaces each {} in the string with each object piped to xargs.Conclusion
When should you use xargs? When the output of a command is the command-line options of another command, use xargs in conjunction with pipes. When the output of a command is the input of another command, use pipes.
References
Powers, Shelley, Peek, Jerry, et al. 2003. Unix Power Tools. Sebastopol, CA: O'Reilly & Associates.
Robbins, Arnold. 1999. Unix in a Nutshell. Sebastopol, CA: O'Reilly & Associates.
Ed Schaefer is a frequent contributor to Sys Admin. He is a software developer and DBA for Intel's Factory Integrated Information Systems, FIIS, in Aloha, Oregon. Ed also hosts the monthly Shell Corner column on UnixReview.com. He can be reached at: shellcorner@comcast.net.
July 2003 UPDATE from the author:
I've received very positive feedback on my xargs article. Other readers have shared constructive criticism concerning:
1. When using the duplicate directory tree "one-liner", reader Peter Ludemann suggests using the
mkdir -poption:find . -type d -print|sed 's@^@/usr/project/@'|xargs mkdir -pinstead of :find . -type d -print|sed 's@^@/usr/project/@'|xargs mkdirmkdir's "-p" option creates parent directories as needed, and doesn't error out if one exists. Additionally,/usr/projectdoes not have to exist.2. Ludemann, in addition to reader Christer Jansson, commented that spaces in directory names renders the duplicate directory tree completely useless.
Although I'm unable to salvage the duplicate directory command, for those
findandxargsversions that support -0 (probably GNU versions only), you might try experimenting with:find ... -print0 | xargs -0 ...Using Ludemann's email example, suppose your current directory structure contains:foo bar foo bar
find . -type f -print | xargs -n 1incorrectly produces:foo bar foo barwhilefind . -type f -print0 | xargs -0 -n 1delivers the correct results:foo bar foo barAccording to the 7.1 Red Hat Linux man page forxargsandfind, the -0 doesn't use the null terminator for file names disabling the special meaning of white space.3. Reader Peter Simpkin asks the question, "Does the use of
xargsonly operate after thefindcommand has completed?find. -type f -name "*.txt" -print | xargs rmIf not, I was under the impression that the above was a bad idea as it is modifying the current directory thatfindis working from, or at least this is what people have told me, and, thus the results offindare then undefined."My response is "no". Any Unix command that supports command-line arguments is an
xargscandidate. The results of thefindcommand are as valid as the output of thelscommand:# remove files ending with .txt in current directory ls *.txt|xargs rmIf a command such as this is valid:chmod 444 1.txt 2.txt 3.txtthen:find . \( -name 1.txt -o -name 2.txt -o -name 3.txt \) -print|xargs chmod 444is valid.In closing, If I had the opportunity to rewrite "Using the Xargs Command", it would look somewhat different.
[ Nov 6, 2000 ] Re GNU enhancement -- $(xargs cmd, list) by Reid Madsen
From: Reid Madsen
Subject: Re: GNU enhancement -- $(xargs cmd, list)
Date: Mon, 6 Nov 2000 19:42:10 -0600 (CST)
> Date: 6 Nov 2000 16:56:30 -0600 > From: Reid Madsen <address@bogus.example.com> > > I also thought about using the _POSIX_ARG_MAX and ARG_MAX symbols to > determine > when the xargs approach was really needed. If the command line is within > limits, then > > $(xargs cmd, list) > > would expand to: > > cmd list > > Do you believe this is doable/portable? > > Reid > > > FYI, a quick perusal of our systems shows: > > POSIX_ARG_MAX ARG_MAX > ------------- ------- > Solaris 4096 1MB > HP 4096 2MB > AIX 4096 24576 Pathetic! > OSF 4096 38912 Pathetic! > NT 4096 14500 Pathetic ** 2 ! > > Gotta love those 2-4 byte per arg limits on AIX, OSF, and NT. After experimenting with this on Solaris for about 3 hours, I've come to the conclusion that this is way to complicated. The 'exec' man page states that the error E2BIG is returned when the sum of the command length and environment length exceeds ARG_MAX. So, armed with that information I when out and created a Makefile with enough big arguments to push it right up to the edge. Adding a single character would case make to fail with: make: execvp: num_args: Arg list too long However the 'edge' was nowhere close to the size of the command line + environment. It's off by about 100K. Yuck! So, instead, I've decided that in addtion to the $(XARGS) variable that GNUmake should also define a $(XARGS_LEN) variable. Which will be used to measure the length of the command line. When less the $(XARGS_LEN), then a normal command is launched, otherwise xargs is launched as" xargs -s $(XARGS_LEN) cmd << tmpfile In our build process, based on IMAKE, we can set XARGS_LEN differently for the different platforms we build on. IMO, this is probably the most flexible. If you have a better idea, I'd be glad to hear it. Reid -- Reid Madsen address@bogus.example.com Senior Member, Tech. Staff (972) 536-3261 (Desk) I2 Technologies (214) 850-9613 (Cellular) -- Making incrementally (without 'clean') since May 18, 2000. Long live incremental make!comp.unix.aix Frequently Asked Questions (Part 2 of 5)
Solution #3 ----------- mount | grep jfs | cut -c27- | cut -d" " -f1 | \ xargs -i backup -${LEVEL} -u -f /dev/rmt1.1 {} > ${DATE}.backup 2>&1Recommended Links
- xargs - Wikipedia, the free encyclopedia
- xargs POSIX specification
- Solaris 9 docs.sun.com man pages section 1 User Commands
- POSIX Xargs man page.
- LinuxPlanet - Tutorials - The Joys of xargs - xargs and find
- Other links specific to command
Copyright © 1996-2009 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. Submit comments This document is an industrial compilation designed and created exclusively for educational use and is placed under the copyright of the Open Content License(OPL). Site uses AdSense so you need to be aware of Google privacy policy. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
Disclaimer:
- The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with.
- We do not warrant the correctness of the information provided or its fitness for any purpose
- In no way this site is associated with or endorse cybersquatters using the term "softpanorama" with other main or country domains (e.g. softpanorama.com) with bad faith intent to profit from the goodwill belonging to someone else.
Last modified: February 07, 2010