Ho scoperto che ciò solleverebbe l'errore "argomento troppo lungo":
ls *.*
E questo non lo solleverebbe:
for file in *.*
do
echo $file
done
Perché?
Ho scoperto che ciò solleverebbe l'errore "argomento troppo lungo":
ls *.*
E questo non lo solleverebbe:
for file in *.*
do
echo $file
done
Perché?
Risposte:
L'errore "argomento troppo lungo" viene E2BIGgenerato dalla execvechiamata di sistema se la dimensione totale degli argomenti (più l'ambiente, su alcuni sistemi) è troppo grande. La execvechiamata è quella che avvia processi esterni, in particolare caricando un altro file eseguibile (c'è una chiamata diversa fork, per eseguire un processo separato il cui codice è ancora dallo stesso file eseguibile). Il forciclo è un costrutto di shell interno, quindi non comporta la chiamata execve. Il comando ls *.*genera l'errore non quando il glob viene espanso ma quando lsviene chiamato.
execvefallisce con l'errore E2BIGquando la dimensione totale degli argomenti del comando è maggiore del ARG_MAX limite . Puoi vedere il valore di questo limite sul tuo sistema con il comando getconf ARG_MAX. (È possibile che sia possibile superare questo limite se si dispone di memoria sufficiente; mantenere sotto ARG_MAXgaranzie che execvefunzioneranno fino a quando non si verifica alcun errore non correlato.)
execvelimite viene imposto dal kernel, pone dei limiti perché gli argomenti devono essere copiati tramite la memoria del kernel in un punto e i processi utente non possono richiedere una quantità arbitraria di memoria della shell. All'interno della shell, non c'è motivo di avere limiti, tutto ciò che si adatta alla memoria virtuale va bene.
Suppongo che nel primo esempio lssia eseguito da bashuna chiamata di sistema fork/ execpair, nel secondo, tutto il lavoro è interno bash.
La execchiamata ha dei limiti, il funzionamento interno bashinvece non ha (o meglio, ha limiti diversi che non hanno nulla a che fare con exec, forse la quantità di memoria disponibile).
execin /usr/include/linux/limits.hgenere, definito come ARG_MAX.
Perché in questo caso lsè un argomento e il numero di argomenti è limitato.
Nel caso del forciclo, è solo un elenco di elementi. Non ci sono limiti (per quanto ne so) per questo.
for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
/bin/bashvs./bin/sh(che è forse un collegamento a trattino)?