Linux终端输入:以4095个字符的限制从终端截断行读取用户输入 [英] Linux terminal input: reading user input from terminal truncating lines at 4095 character limit

查看:420
本文介绍了Linux终端输入:以4095个字符的限制从终端截断行读取用户输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在bash脚本中,我尝试在设置IFS=$'\n'之后使用内置的read命令从标准输入中读取行.如果我将输入内容粘贴到读取中,这些行将被截断为4095个字符的限制.这个限制似乎来自终端的读取,因为它工作得很好:

In a bash script, I try to read lines from standard input, using built-in read command after setting IFS=$'\n'. The lines are truncated at 4095 character limit if I paste input to the read. This limitation seems to come from reading from terminal, because this worked perfectly fine:

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)

我在使用Python脚本时会遇到相同的行为(从终端接受的输入时间不超过4095,但是从管道接受的输入时间):

I experience the same behavior with Python script (did not accept longer than 4095 input from terminal, but accepted from pipe):

#!/usr/bin/python

from sys import stdin

line = stdin.readline()
print('%s' % line)

使用read(2),即使C程序的工作原理相同:

Even C program works the same, using 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;
}

在所有情况下,我输入的字符都不能超过4095个字符.输入提示停止接受字符.

In all cases, I cannot enter longer than about 4095 characters. The input prompt stops accepting characters.

问题1::在Linux系统(至少是Ubuntu 10.04和13.04)中,是否可以从终端以交互方式读取超过4095个字符?

Question-1: Is there a way to interactively read from terminal longer than 4095 characters in Linux systems (at least Ubuntu 10.04 and 13.04)?

问题2:此限制来自何处?

受影响的系统:我注意到在Ubuntu 10.04/x86和13.04/x86中存在此限制,但是Cygwin(至少是最新版本)尚未截断超过10000个字符(自从我进行进一步测试以来,需要使该脚本在Ubuntu中运行).使用的终端:虚拟控制台和KDE konsole(Ubuntu 13.04)和gnome-terminal(Ubuntu 10.04).

Systems affected: I noticed this limitation in Ubuntu 10.04/x86 and 13.04/x86, but Cygwin (recent version at least) does not truncate yet at over 10000 characters (did not test further since I need to get this script working in Ubuntu). Terminals used: Virtual Console and KDE konsole (Ubuntu 13.04) and gnome-terminal (Ubuntu 10.04).

推荐答案

请参考

Please refer to termios(3) manual page, "Canonical and noncanonical mode".

默认情况下,终端(标准输入)处于规范模式;在这种模式下,内核将缓冲输入行,然后再将输入返回给应用程序. Linux的硬编码限制(可能是${linux_source_path}/include/linux/tty.h中定义的N_TTY_BUF_SIZE)设置为4096,从而允许输入4095个字符,而不包括换行符.在非规范模式下,默认情况下内核将不进行缓冲,并且 read( 2)一旦返回输入的单个字符(按下键),系统调用将立即返回.您可以操纵终端设置以读取指定数量的字符,或为非规范模式设置超时,但是根据termios(3)手册页,硬编码限制也为4095.

By default the terminal (standard input) is in canonical mode; in this mode the kernel will buffer the input line before returning the input to the application. The hard-coded limit for Linux (maybe N_TTY_BUF_SIZE defined in ${linux_source_path}/include/linux/tty.h) is set to 4096 allowing input of 4095 characters not counting the ending new line. In noncanonical mode there will by default be no buffering by kernel and the read(2) system call returns immediately once a single character of input is returned (key is pressed). You can manipulate the terminal settings to read a specified amount of characters or set a time-out for non-canonical mode, but then too the hard-coded limit is 4095 per the termios(3) manual page.

Bash read内置命令仍然在非规范模式下工作,如下所示:

Bash read builtin command still works in non-canonical mode as can be demonstrated by the following:

IFS=$'\n'      # Allow spaces and other white spaces.
stty -icanon   # Disable canonical mode.
read line      # Now we can read without inhibitions set by terminal.
stty icanon    # Re-enable canonical mode (assuming it was enabled to begin with).

在添加stty -icanon的修改之后,您可以粘贴超过4096个字符串,并使用bash内置的read命令成功读取它(我成功尝试了超过10000个字符).

After this modification of adding stty -icanon you can paste longer than 4096 character string and read it successfully using bash built-in read command (I successfully tried longer than 10000 characters).

如果将其放在文件中(即使其成为脚本),则可以使用strace查看被调用的系统调用,并且将多次看到read(2)被调用,每次返回一个字符.

If you put this in a file, i.e. make it a script, you can use strace to see the system calls called, and you will see read(2) called multiple times, each time returning a single character.

这篇关于Linux终端输入:以4095个字符的限制从终端截断行读取用户输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆