Answers:
这在很大程度上取决于系统和版本,参数的数量和大小以及环境变量名称的数量和大小。
传统上,在Unix上,该限制(由所报告getconf ARG_MAX
)或多或少地限制了以下内容的累计大小:
'\0'
)'\0'
),按照惯例,环境字符串类似var=value
。请记住,这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
数字的?即您如何计算该序列将在2097152
ARG_MAX大小以下?
这取决于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和很长的文件名上出现问题?
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
或来解决它rsync -a /src/ /dst/
。