xargs 命令长度限制

Ale*_*hel 6 bash xargs jsonlint

我正在使用 jsonlint 对目录中的一堆文件进行 lint(递归)。我写了以下命令:

find ./config/pages -name '*.json' -print0 | xargs -0I % sh -c 'echo Linting: %; jsonlint -V ./config/schema.json -q %;'

它适用于大多数文件,但有些文件我收到以下错误:

Linting: ./LONG_FILE_NAME.json
fs.js:500
 return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                ^
  Error: ENOENT, no such file or directory '%'
Run Code Online (Sandbox Code Playgroud)

对于长文件名,它似乎失败。有没有办法来解决这个问题?谢谢。

编辑1: 发现问题。

-I replstr

对每个输入行执行实用程序,将一个或多个 replstr 替换为实用程序的整行输入,最多替换(如果未指定 -R 标志,则为 5 个)参数。替换完成后,生成的参数将不允许增长超过 255 个字节;这是通过将尽可能多的包含 replstr 的参数连接到实用程序的构造参数来实现的,最多 255 个字节。255 字节的限制不适用于不包含 replstr 的实用程序的参数,此外,实用程序本身不会进行替换。意味着 -x。

编辑 2: 部分解决方案。支持比以前更长的文件名,但仍然没有我需要的那么长。

find ./config/pages -name '*.json' -print0 | xargs -0I % sh -c 'file=%; echo Linting: $file; jsonlint -V ./config/schema.json -q $file;'

Tim*_*imo 8

在类似 BSD 的系统上(例如 Mac OS X)

如果您碰巧使用的是 mac 或 freebsd 等设备,您的xargs实现可能支持 option -J,而不受 option 施加的参数大小限制的影响-I

摘自联机帮助页

-J replstr
If this option is specified, xargs will use the data read from standard input to replace the first occurrence of replstr instead of appending that data after all other arguments. This option will not effect how many arguments will be read from input (-n), or the size of the command(s) xargs will generate (-s). The option just moves where those arguments will be placed in the command(s) that are executed. The replstr must show up as a distinct argument to xargs. It will not be recognized if, for instance, it is in the middle of a quoted string. Furthermore, only the first occurrence of the replstr will be replaced. For example, the following command will copy the list of files and directories which start with an uppercase letter in the current directory to destdir:
/bin/ls -1d [A-Z]* | xargs -J % cp -Rp % destdir
Run Code Online (Sandbox Code Playgroud)

如果您需要多次引用repstr(*向上* TL;DR-J仅替换第一次出现),您可以使用此模式:

echo hi | xargs -J{} sh -c 'arg=$0; echo "$arg $arg"' "{}"
=> hi hi
Run Code Online (Sandbox Code Playgroud)

符合 POSIX 标准的方法

执行此操作的 posix 兼容方法是使用其他一些工具,例如sed构造您想要执行的代码,然后用于xargs指定实用程序。当 xargs 中未使用 repl 字符串时,255 字节限制不适用。xargs POSIX 规范

find . -type f -name '*.json' -print |
  sed "s_^_-c 'file=\\\"_g;s_\$_\\\"; echo \\\"Definitely over 255 byte script..$(printf "a%.0s" {1..255}): \\\$file\\\"; wc -l \\\"\\\$file\\\"'_g" |
  xargs -L1 sh
Run Code Online (Sandbox Code Playgroud)

这当然很大程度上违背了xargs最初的目的,但仍然可以用来利用并行执行xargs -L1 -P10 sh,尽管不是 posix,但它得到了广泛的支持。


Car*_*cas 1

使用-execin find 而不是通过管道传输到 xargs。

find ./config/pages -name '*.json' -print0 -exec echo Linting: {} \; -exec jsonlint -V ./config/schema.json -q {} \;