CP:复制实用程序的最大源文件数参数


11

考虑到/ src /下有无数文件

cp /src/* /dst/

cp成功处理多少个文件?


2
如果参数列表太长(请记住,*会扩展为与glob匹配的所有文件的列表),则可以使用eg IFS="\n" for file in /src/*; do mv "$file" /dst/; done或来解决它rsync -a /src/ /dst/
DopeGhoti 2014年

Answers:


18

这在很大程度上取决于系统和版本,参数的数量和大小以及环境变量名称的数量和大小。

传统上,在Unix上,该限制(由所报告getconf ARG_MAX)或多或少地限制了以下内容的累计大小:

  • 参数字符串的长度(包括终止符'\0'
  • 指向这些字符串的指针数组的长度,因此在64位系统上通常每个参数8个字节
  • 环境字符串的长度(包括终止符'\0'),按照惯例,环境字符串类似var=value
  • 指向这些字符串的指针数组的长度,因此在64位系统上通常每个参数8个字节

请记住,这cp也算作一个参数(是第一个参数)。

在Linux上,取决于版本。最近的行为发生了变化,不再是固定空间。

在Linux 3.11上进行检查时,getconf ARG_MAX现在报告堆栈大小设置的限制的四分之一;如果小于512kiB,则为128kiB。

zsh以下语法):

$ limit stacksize
stacksize       8MB
$ getconf ARG_MAX
2097152
$ limit stacksize 4M
$ getconf ARG_MAX
1048576

该限制是参数和环境字符串的累积大小以及一些开销(我怀疑是由于页面边界上的对齐考虑)。没有考虑指针的大小。

搜索限制,我得到:

$ /bin/true {1..164686}
$ /bin/true {1..164687}
zsh: argument list too long: /bin/true
$ x= /bin/true {1..164686}
$ x=1 /bin/true {1..164686}
zsh: argument list too long: /bin/true

在这种情况下,中断前的最大累积大小为:

$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462

现在,这并不意味着您可以传递一百万个空参数。在64位系统上,一百万个空参数构成一个8MB的指针列表,该列表超出了我的4MiB堆栈大小。

$ IFS=:; /bin/true ${=${(l.1000000..:.)${:-}}}
zsh: killed     /bin/true ${=${(l.1000000..:.)${:-}}}

(您会注意到这不是E2BIG错误。我不确定进程在哪一点被杀死,即使它在execve系统调用中或更高版本中也是如此)。

还要注意(仍在Linux 3.11上),无论堆栈大小如何,单个参数或环境字符串的最大大小为128kiB。

$ /bin/true ${(l.131071..a.)${:-}} # 131072 OK
$ /bin/true ${(l.131072..a.)${:-}} # 131073 not
zsh: argument list too long: /bin/true
$ /bin/true ${(l.131071..a.)${:-}} ${(l.131071..a.)${:-}} # 2x 131072 OK

请您分享一下,您是怎么想到164686数字的?即您如何计算该序列将在2097152ARG_MAX大小以下?
Sergiy Kolodyazhnyy

14

这取决于ARG_MAX的值,该值在系统之间可能会发生变化。要找出系统运行的值(以我的示例显示结果):

$ getconf ARG_MAX
2097152

这与cp您的shell 无关,这是内核施加的限制,exec()如果它们的参数长于,它将不会执行()命令ARG_MAX。因此,如果给定的参数列表的长度cp大于ARG_MAX,则该cp命令将完全不运行。

然后要回答您的主要问题,cp将不处理任何文件,因为它将永远不会使用那么多参数执行。我还应该提到,这不取决于参数的数量,而是取决于它们的长度。可以想象,只有很少但很长的文件名会出现相同的问题。


解决这些错误的方法是循环运行命令:

for file in /src/*; do cp "$file" /dst/; done

这是否意味着即使是较低级的语言C也可能在ARG_MAX和很长的文件名上出现问题?
哈罗德·菲舍尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.