(3 risposte)
Chiuso 2 anni fa.
Contesto della domanda:secondo le specifiche POSIX, ARG_MAX è la lunghezza massima massima di argomenti della riga di comando in exec()
famiglia di funzioni. Il che mi porta a credere che sia il vero numero di argomenti, tuttavia che chiaramente non hanno funzionato:
$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$
Chiaramente, funziona bene, nonostante sia lungo più di 8192 articoli. Secondo la risposta di D.W., il 8192
è presumibilmente la dimensione in kB. Quindi chiaramente l'ipotesi precedente era sbagliata.
È qui che entra in gioco la vera domanda:come faccio a capire la quantità di articoli che effettivamente saranno superare il limite di 8192 kB? In altre parole, che tipo di calcolo devo eseguire per assicurarmi che *.jpg
tipo di glob risulterà in Argument list too long
errore?
Tieni presente che questo non è un duplicato di ciò che definisce la dimensione massima di un singolo argomento di comando. Conosco getconf ARG_MAX
e ulimit -s
valori, questa non è la mia domanda. Ho bisogno di sapere come generare argomenti di dimensioni sufficienti che supereranno il limite . In altre parole, devo trovare un modo per ottenere l'errore, non evitarlo.
Risposta accettata:
Usando getconf ARG_MAX
per generare un lungo elenco di x
e chiamare un'utilità esterna con quello come argomento genererebbe un errore "Elenco di argomenti troppo lungo":
$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long
L'ambiente e la lunghezza della stringa /bin/echo
sarà incluso in ciò che provoca l'errore, quindi possiamo provare a trovare il numero più grande possibile sottraendo questi:
$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin
(Ho iniziato questa shell con env -i sh
, quindi c'è solo il PATH
variabile nell'ambiente)
$ /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long
Ancora troppo a lungo. Di quanto?
i=0
while ! /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
i=$(( i + 1 ))
done
Questo ciclo termina per i=8
.
Quindi ci sono quattro byte di cui non riesco a tenere conto immediatamente (quattro degli otto devono essere per il nome del PATH
variabile d'ambiente). Questi sono i terminatori nulli per le quattro stringhe PATH
, il valore di PATH
, /bin/echo
e la lunga stringa di x
caratteri.
Nota che ciascuno argomento è null terminato, quindi più argomenti hai per il comando, più breve può essere la loro lunghezza combinata.
Inoltre, solo per mostrare l'effetto di un grande ambiente:
$ export BIG=$( perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )
$ /bin/echo hello
sh: /bin/echo: Argument list too long
$ /bin/echo
sh: /bin/echo: Argument list too long