2017/03/18

Difference for option -I of xargs between MAC and Linux

About

Last night, I found that there was a problem on running below script on MAC when I am updating npm’s packages with my dotconfig which works perfectly on Linux.
paste -d' ' -s "$BASEDIR/packages.txt" | \
    xargs -I{} sh -c "echo npm install -g {}; npm install -g {} || exit 255"

Debugging

So here is the content of packages.txt.
eslint@^3.x
babel-eslint@^7.x
eslint-plugin-jsx-a11y@^4.x
eslint-plugin-import@^2.x
eslint-plugin-react@^6.x
eslint-config-airbnb@^14.x
eslint-config-eslint@^4.x
grunt-cli@^1.x
bower@^1.x
phantomjs-prebuilt@2.x
Script (under linux platform) will first echoes following and then install packages as below statement.
npm install -g eslint@^3.x babel-eslint@^7.x eslint-plugin-jsx-a11y@^4.x .....
However, it simply echoes above statement without installing any packages. Therefore, I have tried the 2 statements (paste and xargs) separately. paste works perfectly so that’s the problem of xargs.
After reading man page of xargs in MAC, there is a fundamental difference on -I‘s implementation. Replacements for MAC’s xargs will be executed only if length of the target line is below 255 while Linux one does not has such limitation.
In MAC,
     -I replstr
             Execute utility for each input line, replacing one or more occurrences of replstr in up to
             replacements (or 5 if no -R flag is specified) arguments to utility with the entire line of
             input.  The resulting arguments, after replacement is done, will not be allowed to grow beyond
             255 bytes; this is implemented by concatenating as much of the argument containing replstr as
             possible, to the constructed arguments to utility, up to 255 bytes.  The 255 byte limit does
             not apply to arguments to utility which do not contain replstr, and furthermore, no replacement
             will be done on utility itself.  Implies -x.
In Linux,
       -I replace-str
              Replace occurrences of replace-str in the initial-arguments
              with names read from standard input.  Also, unquoted blanks do
              not terminate input items; instead the separator is the
              newline character.  Implies -x and -L 1.

Solution

Actually, I have failed to find an alternative in MAC. So I simply split the statement into two.
paste -d' ' -s "$BASEDIR/packages.txt" | \
    xargs -I{} sh -c "echo npm install -g {}"
paste -d' ' -s "$BASEDIR/packages.txt" | \
    xargs -I{} sh -c "npm install -g {} || exit 255"

沒有留言:

張貼留言