17

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

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 的输入,但从管道接受):

#!/usr/bin/python

from sys import stdin

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

甚至 C 程序也一样,使用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 个字符。输入提示停止接受字符。

问题 1:有没有办法在 Linux 系统(至少 Ubuntu 10.04 和 13.04)中从终端交互式读取超过 4095 个字符?

问题2:这个限制来自哪里?

受影响的系统:我在 Ubuntu 10.04/x86 和 13.04/x86 中注意到了这个限制,但是 Cygwin(至少是最近的版本)在超过 10000 个字符时还没有截断(没有进一步测试,因为我需要让这个脚本在 Ubuntu 中工作)。使用的终端:虚拟控制台和 KDE konsole(Ubuntu 13.04) 和gnome-terminal(Ubuntu 10.04)。

4

3 回答 3

11

请参阅termios(3)手册页的“规范和非规范模式”部分。

通常,终端(标准输入)处于规范模式;在这种模式下,内核将在将输入返回给应用程序之前缓冲输入行。Linux 的硬编码限制(N_TTY_BUF_SIZE定义在 中${linux_source_path}/include/linux/tty.h)设置为 4096,允许输入 4095 个字符,不包括结束的新行。您还可以查看文件${linux_source_path}/drivers/tty/n_tty.c、函数n_tty_receive_buf_common()和上面的注释。

在非规范模式下,默认情况下内核不会缓冲,并且一旦返回单个输入字符(按下键) , read(2)系统调用就会立即返回。您可以操纵终端设置以读取指定数量的字符或为非规范模式设置超时,但硬编码限制也是每个termios(3)手册页的 4095(以及上面提到的评论n_tty_receive_buf_common())。

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

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 个字符)。

如果你把它放在一个文件中,即把它变成一个脚本,你可以用它strace来查看调用的系统调用,你会看到read(2)调用了多次,每次在你输入输入时返回一个字符。

于 2013-08-02T13:45:19.610 回答
-1

我没有适合您的解决方法,但我可以回答问题 2。在 linux 中,PIPE_BUF 设置为 4096(在 中limits.h)如果您向管道写入超过 4096 的内容,它将被截断。

来自/usr/include/linux/limits.h

#ifndef _LINUX_LIMITS_H
#define _LINUX_LIMITS_H

#define NR_OPEN         1024

#define NGROUPS_MAX    65536    /* supplemental group IDs are available */
#define ARG_MAX       131072    /* # bytes of args + environ for exec() */
#define LINK_MAX         127    /* # links a file may have */
#define MAX_CANON        255    /* size of the canonical input queue */
#define MAX_INPUT        255    /* size of the type-ahead buffer */
#define NAME_MAX         255    /* # chars in a file name */
#define PATH_MAX        4096    /* # chars in a path name including nul */
#define PIPE_BUF        4096    /* # bytes in atomic write to a pipe */
#define XATTR_NAME_MAX   255    /* # chars in an extended attribute name */
#define XATTR_SIZE_MAX 65536    /* size of an extended attribute value (64k) */
#define XATTR_LIST_MAX 65536    /* size of extended attribute namelist (64k) */

#define RTSIG_MAX     32

#endif
于 2013-08-02T11:58:21.927 回答
-3

问题绝对不是 read() ;因为它可以读取任何有效的整数值。问题来自堆内存或管道大小..因为它们是大小的唯一可能限制因素..

于 2013-08-13T00:55:05.167 回答