I am using jsonlint to lint a bunch of files in a directory (recursively). I wrote the following command:
find ./config/pages -name '*.json' -print0 | xargs -0I % sh -c 'echo Linting: %; jsonlint -V ./config/schema.json -q %;'
It works for most files but some files I get the following error:
Linting: ./LONG_FILE_NAME.json
fs.js:500
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
^
Error: ENOENT, no such file or directory '%'
It appears to fail for long filenames. Is there a way to fix this? Thanks.
Edit 1: Found the problem.
-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 con-structed 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.
Edit 2: Partial solution. Supports longer file names than before but still not as long as I need.
find ./config/pages -name '*.json' -print0 | xargs -0I % sh -c 'file=%; echo Linting: $file; jsonlint -V ./config/schema.json -q $file;'
If you happen to be on a mac or freebsd etc. your
xargs
implementation may support option-J
which does not suffer from the argument size limits imposed on option-I
.Excert from manpage
If you need to refer to the
repstr
multiple times you can use this pattern:Use
-exec
in find instead of piping to xargs.find ./config/pages -name '*.json' -print0 -exec echo Linting: {} \; -exec jsonlint -V ./config/schema.json -q {} \;
The limit on
xargs
's command line length is imposed by the system (not an environment) variableARG_MAX
. You can check it like:Surprisingly, there doesn't not seem to be a way to change it, barring kernel modification.
But even more surprising that
xargs
by default gets capped to a much lower value, and you can increase with-s
option. Still, ARG_MAX is not the value you can set after-s
— acc. toman xargs
you need to subtract size of environment, plus some "headroom", no idea why. To find out the actual number use the following command (alternatively, using an arbitrary big number for-s
will result in a descriptive error):So you need to run
… | xargs -s 2092120 …
, e.g. with your command: