为什么数字如此不规则?
echo {1..200000} | xargs perl -E 'say "ok:", scalar @ARGV'
ok:23691
ok:21840
ok:21840
ok:21840
ok:20261
ok:18720
ok:18720
ok:18720
ok:18720
ok:15648
Run Code Online (Sandbox Code Playgroud)
标准参数长度更文明。
perl -E' say "1 " x 900000' | xargs perl -E 'say "ok:", scalar @ARGV'
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:65520
ok:48240
Run Code Online (Sandbox Code Playgroud)
关键因素是什么?
重要的数字是(所有)参数的总长度,以及 xargs 决定使用的命令缓冲区大小。
第一个取决于您运行的命令的固定命令行,参数 xargs 给出每次调用。perl -E 'say "ok:", scalar @ARGV'是 32 字节,计算终止字符串的 NUL 字节(即perl<NUL>-E<NUL>say "ok:", scalar @ARGV<NUL>。在第二个示例中,所有参数都是两个字节,1<NUL>因此 32 + 65520 * 2 字节,或 131072 B = 128 * 1024 B = 128 kB。
显然在第一个例子中,参数的长度不同,给出不同的计数,但逻辑应该是相同的。例如,第二到第四次运行的 21840 args 匹配 5 位参数(每个 6 字节):21840 * 6 + 32 = 131072。
命令缓冲区的大小可能取决于实现,但 GNU xargs 可以用 显示它xargs --show-limits,在我的 Linux 上,我得到:
$ echo | xargs --show-limits
Your environment variables take up 2305 bytes
POSIX upper limit on argument length (this system): 2092799
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2090494
Size of command buffer we are actually using: 131072
Maximum parallelism (--max-procs must be no greater): 2147483647
Run Code Online (Sandbox Code Playgroud)
查看倒数第二行,这是完全相同的数字。
您可以更改它使用的缓冲区的大小-s,例如仅使用 10 kB 缓冲区:
$ perl -E' say "1 " x 90000' | xargs -s 10240 perl -E 'say "ok:", scalar @ARGV'
ok:5104
ok:5104
ok:5104
...
Run Code Online (Sandbox Code Playgroud)
当然还有-n限制单个参数的数量:
$ echo {1..200000} | xargs -n 10000 perl -E 'say "ok:", scalar @ARGV'
ok:10000
ok:10000
ok:10000
...
Run Code Online (Sandbox Code Playgroud)
--show-limits 提到环境变量,因为它们与命令行参数使用相同的空间,如果您将缓冲区大小提高到足够接近系统最大值,它们的大小也开始重要。
我不确定系统是否还会根据限制计算指向参数字符串的指针的大小,但至少 xargs 似乎并不关心这一点。
| 归档时间: |
|
| 查看次数: |
318 次 |
| 最近记录: |