Many simple commands using xargs could be rewritten as commands using subshells. For instance, here is something I was using earlier today, to concatenate the ten largest binaries in /usr/bin, written using a subshell vs xargs:subshell:$ cat $(du -sh /usr/bin/* | sort -h | tail | cut -d        -f 2 | tr \n  )xargs:$ du -sh /usr/bin/* | sort -h | tail | cut -d        -f 2 | tr \n   | xargs catSo when should you use a subshell and when should you use xargs?NOTE:The delimiter for cut is a hard tab, which apparently doesn't display properly on SE.
When should you use subshells vs `xargs`?
shell;command line;xargs;conventions;subshell
This is a slightly opinionated question but I'll just say this, it's highly dependent on 2 things:What is the command you're going to run?How many instances you're going to run?If you're likely to run dozens to 100's of the same process, then xargs makes the most sense. Also if the processes are going to be expensive to start up, xargs is likely the best route to go. If however there will only be a handful of instances of the command, then running them in a subshell is fine. If the length of the arguments produced by the subshell will be extremely long, then you'd want to use xargs. But this limit is pretty extreme, typically 2MB-4MB of characters, so it's unlikely that you'd exceed it. You can check like this:$ xargs --show-limits < /dev/nullYour environment variables take up 4805 bytesPOSIX upper limit on argument length (this system): 2090299POSIX smallest allowable upper limit on argument length (all systems): 4096Maximum length of command we could actually use: 2085494Size of command buffer we are actually using: 131072By the way, neither of these commands appear to work. The cut -d        -f2 is not valid, cut can only take a single character as the delimiter. Try this instead:$ du -sh /usr/bin/* | sort -h | awk 'NR<=10 {print $2}' | tr \n  -or-$ du -sh /usr/bin/* | sort -h | tail | cut -f2- | tr \n  Using awk here will likely cause you issues if you have any filenames or directories with spaces, so use it with caution.$ lltotal 0-rw-rw-r--. 1 saml saml 0 Feb 22 19:47 file 1-rw-rw-r--. 1 saml saml 0 Feb 22 19:47 file 2$ du -sh * | sort -h | awk 'NR<=10 {print $2}' | tr \n  file file $I'd use the cut -f2- method, but that's just me, others' might give you a more sophisticated awk solution, but use what makes the most sense to you.Using awk + catNOTE: When piping output to xargs there is no need to call cat, xargs will automatically echo the output it's passed, by default.$ du -sh * | sort -h | tail | cut -f2- | tr \n   | xargsfile 1 file 10 file 2 file 3 file 4 file 5 file 6 file 7 file 8 file 9EDIT #1If you're using tabs to delimit with cut you don't need to do so explicitly, it defaults to that.   -d, --delimiter=DELIM          use DELIM instead of TAB for field delimiter