GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie verursacht man den Fehler „Argumentliste zu lang“?

Für diese Frage gibt es hier bereits Antworten :Was definiert die maximale Größe für ein einzelnes Befehlsargument?

(3 Antworten)
Vor 2 Jahren geschlossen.

Kontext für die Frage:Gemäß den POSIX-Spezifikationen ist ARG_MAX die maximale Länge von Befehlszeilenargumenten zu exec() Familie von Funktionen. Was mich glauben lässt, dass das die tatsächliche Zahl ist Argumente, aber das hat eindeutig nicht funktioniert:

$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$ 

Dies funktioniert natürlich gut, obwohl es eine Länge von über 8192 Elementen hat. Laut der Antwort von D.W. der 8192 ist angeblich Größe in kB. Die vorherige Annahme war also eindeutig falsch.

Hier kommt die eigentliche Frage ins Spiel:Wie finde ich die Anzahl der Artikel heraus, die tatsächlich werden werden Überschreitung der 8192-kB-Grenze? Mit anderen Worten, welche Art von Berechnung muss ich durchführen, um sicherzustellen, dass *.jpg Glob-Typ führt zu Argument list too long Fehler ?

Bitte beachten Sie, dass dies kein Duplikat von Was definiert die maximale Größe eines einzelnen Befehlsarguments ist. Ich kenne getconf ARG_MAX und ulimit -s Werte, das ist nicht meine Frage. Ich muss wissen, wie man genügend Argumente in der Größe generiert, die über dem Limit liegen . Mit anderen Worten, ich muss einen Weg finden, den Fehler zu bekommen, nicht ihn vermeiden.

Akzeptierte Antwort:

Verwenden von getconf ARG_MAX um eine lange Liste von x zu generieren und der Aufruf eines externen Dienstprogramms mit diesem Argument als Argument würde einen „Argument list too long“-Fehler erzeugen:

$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long

Die Umgebung und die Länge des Strings /bin/echo wird in der Ursache des Fehlers enthalten sein, sodass wir versuchen können, die größtmögliche Zahl zu finden, indem wir diese subtrahieren:

$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin

(Ich habe diese Shell mit env -i sh gestartet , also gibt es nur den PATH Variable in der Umgebung)

$ /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

Immer noch zu lang. Um wie viel?

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

Diese Schleife endet für i=8 .

Also gibt es vier Bytes, die ich nicht sofort erklären kann (vier der acht müssen für den Namen sein des PATH Umgebungsvariable). Dies sind die Nullterminatoren für die vier Strings PATH , der Wert von PATH , /bin/echo und die lange Zeichenfolge von x Zeichen.

Siehe auch:Linux – Warum dauert es so lange, einen USB-Stick zu erkennen?

Beachten Sie, dass jeder Das Argument ist nullterminiert. Je mehr Argumente Sie also für den Befehl haben, desto kürzer kann die kombinierte Länge von ihnen sein.

Nur um den Effekt einer großen Umgebung zu zeigen:

$ 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

Linux
  1. /usr/bin vs. /usr/local/bin Unter Linux?

  2. Warum zeigt /bin/sh auf /bin/dash und nicht auf /bin/bash?

  3. Wie finde ich heraus, aus welchem ​​Ordner ein Prozess läuft?

  4. Wann muss ich #!/bin/bash und wann #!/bin/sh verwenden?

  5. Unterschied zwischen /bin und /usr/bin

So beheben Sie /bin/rm:kann nicht ausgeführt werden [Argumentliste zu lang]

bash:/bin/tar:Argumentliste zu lang, wenn viele Dateien mit tar komprimiert werden

Wie kann man eine Liste von Wörtern in einer Shell-Zeichenfolge umkehren?

Wann sollte ich /dev/shm/ verwenden und wann sollte ich /tmp/?

So kopieren Sie einen öffentlichen Schlüssel auf Ihren Server

/bin Inhalt nach /usr/bin verschoben, rückgängig machen möglich?