Descobri que isso geraria o erro "argumento muito longo":
ls *.*
E isso não aumentaria:
for file in *.*
do
echo $file
done
Por quê?
Descobri que isso geraria o erro "argumento muito longo":
ls *.*
E isso não aumentaria:
for file in *.*
do
echo $file
done
Por quê?
Respostas:
O erro "argumento muito longo" é E2BIGgerado pela execvechamada do sistema se o tamanho total dos argumentos (mais o ambiente, em alguns sistemas) for muito grande. A execvechamada é aquela que inicia processos externos, carregando especificamente um arquivo executável diferente (há uma chamada diferente fork, para executar um processo separado cujo código ainda é do mesmo arquivo executável). O forloop é uma construção de shell interna, portanto, não envolve chamadas execve. O comando ls *.*gera o erro não quando o glob é expandido, mas quando lsé chamado.
execvefalha com o erro E2BIGquando o tamanho total dos argumentos para o comando é maior que o ARG_MAX limite . Você pode ver o valor desse limite em seu sistema com o comando getconf ARG_MAX. (É possível que você ultrapasse esse limite se tiver memória suficiente; mantendo as ARG_MAXgarantias de que execvefuncionará enquanto não ocorrer nenhum erro não relacionado.)
execvelimite é imposto pelo kernel, coloca limites porque os argumentos precisam ser copiados via memória do kernel em um ponto e os processos do usuário não podem solicitar uma quantidade arbitrária de memória shell. Dentro do shell, não há razão para ter qualquer limite, tudo o que se encaixa na memória virtual é bom.
Suponho que no primeiro exemplo lsseja executado bashatravés de uma chamada de sistema fork/ execpair, no segundo, todo o trabalho seja interno bash.
A execchamada tem limites, o trabalho interno em bashvez disso não tem (ou melhor, possui limites diferentes que não têm nada a ver com exec, talvez a quantidade de memória disponível).
execem /usr/include/linux/limits.hgeral, definido como ARG_MAX.
Porque, no caso ls, é um argumento, e o número de argumentos é limitado.
No caso do forciclo, é apenas uma lista de itens. Não há limites (até onde eu saiba) para isso.
for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
/bin/bashvs./bin/sh(que talvez seja um link para o dash)?