考虑到 /src/ 下有无数个文件
cp /src/* /dst/
Run Code Online (Sandbox Code Playgroud)
cp
将成功处理多少个文件?
Sté*_*las 21
这在很大程度上取决于系统和版本、参数的数量和大小以及环境变量名称的数量和大小。
传统上,在 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
Run Code Online (Sandbox Code Playgroud)
该限制是参数和环境字符串的累积大小以及一些开销(我怀疑是由于页面边界的对齐考虑)。不考虑指针的大小。
寻找极限,我得到:
$ /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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,中断前的最大累积大小为:
$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462
Run Code Online (Sandbox Code Playgroud)
现在,这并不意味着您可以传递 100 万个空参数。在 64 位系统上,100 万个空参数构成一个 8MB 的指针列表,这将超过我 4MiB 的堆栈大小。
$ IFS=:; /bin/true ${=${(l[1000000][:])}}
zsh: killed /bin/true ${=${(l[1000000][:])}}
Run Code Online (Sandbox Code Playgroud)
(你会注意到这不是 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
Run Code Online (Sandbox Code Playgroud)
ter*_*don 15
这将取决于可以在系统之间变化的 ARG_MAX 的值。要找出系统运行的值(以我的结果为例):
$ getconf ARG_MAX
2097152
Run Code Online (Sandbox Code Playgroud)
这与cp
您的 shell无关,这是内核强加的限制,exec()
如果( ) 命令的参数长于ARG_MAX
. 因此,如果您提供的参数列表的长度cp
大于 ARG_MAX,则该cp
命令根本不会运行。
那么要回答您的主要问题,cp
将不处理任何文件,因为它永远不会使用这么多参数执行。我还应该提到,这不取决于参数的数量,而是取决于它们的长度。可以想象,对于很少但很长的文件名,您可能会遇到同样的问题。
解决这些错误的方法是在循环中运行您的命令:
for file in /src/*; do cp "$file" /dst/; done
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
25900 次 |
最近记录: |