Linux-terminal-Eingang: Lesen der Benutzer eine Eingabe vom terminal mit dem abschneiden von Linien zu 4095 Zeichen limit
In ein bash-script, ich versuche zum Lesen von Zeilen von der Standardeingabe, mit built-in read
Befehl nach Einstellung IFS=$'\n'
. Die Zeilen abgeschnitten sind, an 4095 Zeichen limit, wenn ich einfügen-Eingang zu Lesen. Diese Einschränkung scheint zu kommen aus dem Lesen vom terminal, denn dieser arbeitet völlig in Ordnung:
fill=
for i in $(seq 1 94); do fill="${fill}x"; done
for i in $(seq 1 100); do printf "%04d00$fill" $i; done | (read line; echo $line)
Erlebe ich das gleiche Verhalten mit einem Python-Skript (nicht akzeptieren länger als 4095 Eingabe vom terminal, aber akzeptiert, von Rohr):
#!/usr/bin/python
from sys import stdin
line = stdin.readline()
print('%s' % line)
Sogar C-Programm funktioniert auf die gleiche, mit read(2)
:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
char buf[32768];
int sz = read(0, buf, sizeof(buf) - 1);
buf[sz] = '\0';
printf("READ LINE: [%s]\n", buf);
return 0;
}
In allen Fällen, ich kann nicht geben Sie mehr als 4095 Zeichen. Der Eingabe-prompt Stoppt annehmen Zeichen.
Frage-1: gibt es eine Möglichkeit, interaktiv Lesen vom terminal länger als 4095 Zeichen in Linux-Systemen (mindestens Ubuntu 10.04 und 13.04)?
Frage-2: Woher diese Einschränkung kommt?
Betroffene Systeme: ich bemerkte, dass diese Einschränkung in Ubuntu 10.04/x86 und 13.04/x86, aber Cygwin (aktuelle version zumindest) nicht abgeschnitten noch auf über 10000 Zeichen (nicht weiter testen, da die ich brauche, um dieses Skript funktioniert in Ubuntu). Terminals verwendet: Virtuelle Konsole und KDE konsole
(Ubuntu 13.04) und gnome-terminal
(Ubuntu 10.04).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Entnehmen Sie bitte termios(3) Handbuch Seite, "Kanonische und mitgliedattribut-Modus".
Standardmäßig das terminal (standard-Eingabe) ist im kanonischen Modus; in diesem Modus wird der kernel-Puffer die Zeile eingeben, bevor er die Eingabe an die Anwendung. Das hartcodierte limit für Linux (vielleicht
N_TTY_BUF_SIZE
definiert in${linux_source_path}/include/linux/tty.h
) ist auf 4096 gesetzt erlaubt die Eingabe von 4095 Zeichen, die nicht zählen, das Ende der neuen Zeile. In mitgliedattribut-Modus wird es standardmäßig werden keine Pufferung von kernel und die Lesen(2) system-Aufruf gibt sofort ein einzelnes Zeichen der Eingabe wird zurückgegeben (Taste gedrückt wird). Sie können manipulieren die terminal-Einstellungen Lesen einer bestimmten Menge von Zeichen oder Satz ein time-out für nicht-kanonischen Modus, aber dann ist auch das hartcodierte limit 4095 pro dietermios(3)
manual-Seite.Bash
read
builtin-Befehl arbeitet immer noch im nicht-kanonischen Modus, wie kann nachgewiesen werden, indem die folgenden:Nach dieser änderung hinzufügen
stty -icanon
können Sie fügen Sie mehr als 4096 Zeichen-string und Lesen Sie es erfolgreich mitbash
built-inread
Befehl (habe ich erfolgreich ausprobiert, die länger als 10000 Zeichen).Wenn man diese in einer Datei, D. H. ein Skript verwenden, können Sie
strace
zu sehen, ruft das system genannt, und Sie werden sehenread(2)
rief mehrere Male, jedes mal, wenn die Rückkehr ein einzelnes Zeichen.Habe ich nicht einen workaround für dich, aber ich kann die Antwort zu Frage 2.
In linux PIPE_BUF ist auf 4096 gesetzt (in
limits.h
), Wenn Sie ein schreiben von mehr als 4096 zu einem Rohr abgeschnitten.Vom
/usr/include/linux/limits.h
:Das problem ist definitiv nicht die read() ; wie kann es Lesen, bis zu jeden gültigen integer Wert. Das problem kommt aus dem heap-Speicher oder das Rohr Größe.. denn Sie sind die einzigen möglich, die begrenzenden Faktoren für die Größe..