Respostas:
Isso depende muito do sistema e da versão, do número e tamanho dos argumentos e do número e tamanho dos nomes de variáveis de ambiente.
Tradicionalmente no Unix, o limite (conforme relatado por getconf ARG_MAX
) era mais ou menos no tamanho cumulativo de:
'\0'
)'\0'
), sendo uma sequência de ambiente por convenção algo parecido var=value
.Tendo em mente que cp
também conta como argumento (é o primeiro argumento).
No Linux, isso depende da versão. O comportamento mudou recentemente, onde não é mais um espaço fixo.
A verificação no Linux 3.11 getconf ARG_MAX
agora relata um quarto do limite definido no tamanho da pilha, ou 128kiB, se for menor que 512kiB).
( zsh
sintaxe abaixo):
$ limit stacksize
stacksize 8MB
$ getconf ARG_MAX
2097152
$ limit stacksize 4M
$ getconf ARG_MAX
1048576
Esse limite está no tamanho cumulativo das seqüências de argumento e ambiente e em algumas sobrecargas (suspeito devido à consideração do alinhamento nos limites da página). O tamanho dos ponteiros não é levado em consideração.
Procurando pelo limite, recebo:
$ /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
O tamanho cumulativo máximo antes da quebra nesse caso é:
$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462
Agora, isso não significa que você pode transmitir 1 milhão de argumentos vazios. Em um sistema de 64 bits, 1 milhão de argumentos vazios formam uma lista de ponteiros de 8 MB, que estaria acima do tamanho da minha pilha de 4MiB.
$ IFS=:; /bin/true ${=${(l.1000000..:.)${:-}}}
zsh: killed /bin/true ${=${(l.1000000..:.)${:-}}}
(você notou que não é um erro E2BIG. Não sei em que momento o processo será morto lá, se estiver dentro da execve
chamada do sistema ou posterior).
Observe também (ainda no Linux 3.11) que o tamanho máximo de um único argumento ou sequência de ambiente é 128kiB, independentemente do tamanho da pilha.
$ /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
número? ou seja, como você calculou que a sequência estaria no 2097152
tamanho ARG_MAX?
Isso dependerá do valor de ARG_MAX que pode mudar entre os sistemas. Para descobrir o valor da execução do seu sistema (mostrando o resultado no meu como um exemplo):
$ getconf ARG_MAX
2097152
Isso não tem nada a ver com o cp
seu shell, é um limite imposto pelo kernel, não executará exec()
comandos ( ) se seus argumentos forem maiores que ARG_MAX
. Portanto, se o comprimento da lista de argumentos que você forneceu cp
for maior que ARG_MAX, o cp
comando não será executado.
Para responder à sua pergunta principal, cp
o processo não será processado, pois nunca será executado com tantos argumentos. Devo também mencionar que isso não depende do número de argumentos, mas de seu comprimento. É possível que você possa ter o mesmo problema com nomes de arquivos muito poucos, mas muito longos.
A maneira de contornar esses erros é executar seu comando em um loop:
for file in /src/*; do cp "$file" /dst/; done
C
podem ter problemas com ARG_MAX e nomes de arquivos realmente longos?
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
oursync -a /src/ /dst/
.