xargs

XARGS error, not replacing on FreeBSD

by admin on

…..at least this was what I thought when I started writing this post. Well, what I found is that in some corner cases, FreeBSD’s xargs command doesn’t behave as expected – as behaves in other OS. Unfortunately, many programs on different OSs are really different programs with similar functionalities and the same name.

Let’s say that  I had this line of bash:

Where:

  • find /path-of-my-directory -mindepth 1 -maxdepth 1 -type d: 
    • find /path-of-my-directory : search within /path-of-my-directory
    • -mindepth 1 -maxdepth 1 : consider just level 1 files and directory
    • -type d: consider only directories
  • | xargs -I {}  bash -c “/scripts/directory/InnerScript –very {} –long {} –series {} –of {} –parameters {} –with {} –something {} –to –replace {}” :
    • | xargs : pipe (forward) results to xargs
    • -I {} : replace {} with piped (forwarded) result
    • bash : shell to use
    • -c “/scripts/directory/InnerScript –very {} –long {} –series {} –of {} –parameters {} –with {} –something {} –to –replace {}” : command line to execute

This command worked well on Ubuntu and other Debian-based servers, but had an odd behaviour on FreeBSD. Sometimes it replaced correctly all {}, some other times it replaced just some {}, some other times it didn’t replace any {} .

What I found is that xargs on FreeBSD has at least one important difference from its equivalent on Ubuntu, at least regarding the command to execute: by default total length of the command must be less than 255 bytes on FreeBSD, at least by default (FreeBSD.org – xargs man, see -I option). Let’s say (even if it is obviously not precise) that it must be less than 255 characters. On Ubuntu, the same default value is 128Kbytes – or less if the maximum system command line length is less than this (Ubuntu Manpage – xargs, see -s option); on my Ubuntu system maximum command line length was about 200Kbyte; on my FreeNAS it was 250Kbyte.

So, on FreeBSD, if you have a long string, you must add -S <number greater than 255> to your commad line: