Contexto para a pergunta: De acordo com as especificações do POSIX , ARG_MAX é o comprimento máximo dos argumentos de linha de comando para a exec()
família de funções. O que me leva a acreditar que esse é o número real de argumentos, no entanto, isso claramente não funcionou:
$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$
Claramente, isso funciona bem, apesar de ter mais de 8192 itens. De acordo com a resposta do DW , o 8192
tamanho é supostamente em kB. Então, claramente, a suposição anterior estava errada.
É aqui que entra a questão real: Como descubro a quantidade de itens que realmente ficarão acima do limite de 8192 kB? Em outras palavras, que tipo de computação devo realizar para garantir que esse *.jpg
tipo de glob resultará em Argument list too long
erro?
Observe que isso não é uma duplicata de O que define o tamanho máximo do argumento de comando único . Conheço getconf ARG_MAX
e ulimit -s
valores, essa não é a minha pergunta. Eu preciso saber como gerar argumentos suficientes em tamanho que estarão acima do limite . Em outras palavras, preciso encontrar uma maneira de obter o erro, não evitá-lo.
Usar
getconf ARG_MAX
para gerar uma longa listax
e chamar um utilitário externo com isso como seu argumento geraria um erro "Lista de argumentos muito longa":O ambiente e o comprimento da string
/bin/echo
serão incluídos no que faz o erro ocorrer, então podemos tentar encontrar o maior número possível subtraindo estes:(Comecei este shell com
env -i sh
, então há apenas aPATH
variável no ambiente)Ainda muito tempo. Por quanto?
Este loop sai para
i=8
.Portanto, há quatro bytes que não posso explicar imediatamente (quatro dos oito devem ser para o nome da
PATH
variável de ambiente). Esses são os terminadores nulos para as quatro stringsPATH
, o valor dePATH
e/bin/echo
a longa string dex
caracteres.Observe que cada argumento é terminado em nulo, portanto, quanto mais argumentos você tiver para o comando, menor será o comprimento combinado deles.
Além disso, apenas para mostrar o efeito de um ambiente grande:
Em muitas distribuições Linux, você pode descobrir qual é o valor atual de ARG_MAX executando
Uma maneira simples de gerar a mensagem "Lista de argumentos muito longa" é fornecer uma lista de argumentos longa; por exemplo, no meu sistema
funciona, mas
produz
Para uma discussão aprofundada, consulte " Erro na lista de argumentos muito longa para comandos rm, cp, mv " no Stack Overflow.
PS O comprimento em questão é a quantidade real de memória necessária para armazenar os argumentos e o ambiente. Não está relacionado com o número de argumentos.
Em vez de listar todos os arquivos do sistema, o que demora uma eternidade e não funciona em sistemas esparsos, o comando
é uma maneira muito mais rápida (163ms) de gerar o erro. Para mim
ARG_MAX
é2097152
(2.097.152 na ordem de 2 milhões), mas o comando ainda apresenta erros.Se o seu shell não tiver
{start..end}
, você pode usar o um pouco mais lento (mas ainda mais rápido do que listar arquivos)Se qualquer um dos comandos não funcionar, apenas aumente o valor final até que funcione, até
bash
ficar sem memória ou atéseq
não poder contar mais.Para facilitar, inicie um novo shell (
exit
quando concluído) e defina o limite para um valor menor (100kbytes):Com o exemplo que você usou, o erro pode ser acionado:
Mas é melhor usar algo como
echo
. Entenda que um builtin pode não acionar um erro, este comando deve funcionar corretamente:Observe também que a quantidade de bytes está bem acima do limite definido acima (1,1 Mbyte):
Mas este comando não funcionará:
O limite é definido pelo tamanho da lista de argumentos em bytes adicionados ao tamanho do ambiente do shell.