Intereting Posts
Проблема с настройкой WPA2 с помощью wpa_supplicant Почему завершение man-страницы не выполняется после su? Как перенаправить HTTP-запросы на локальный сервер Apache при подключении к Интернету? Проблема с конкретными приложениями? Окно программы Window, работающей под Wine, по умолчанию не отображается Как удалить все, кроме числовых каталогов верхнего уровня? xkbcomp не обновляет keymap для запуска xterms? Ошибка установки linux-firmware_1.157.10: «невозможно удалить» /lib/firmware/brcm/brcmfmac43362-sdio.bin ': разрешение отклонено. " Как удалить несколько строк из файла с помощью оболочки разделение файлов на основе их имени Bash – Замена случайного числа между кавычками Как отключить сообщение спама systemd «Время было изменено» в / var / log / syslog на Debian jessie? Какая версия unix из оболочки? Есть ли способ установить размер списка истории в bash более чем на 5000 строк? diff сообщает о той же строке, что и в двух файлах

Как читать через 4k вход без новых строк на терминале?

Поэтому у меня много данных БЕЗ НОВЫХ ЛИНИЙ в буфере обмена (это большой SVG-файл в одной строке). я пошел

$ cat >file.svg 

затем попытался вставить (в терминале Gnome), но были приняты только первые 4kB-символы.

Я предполагаю, что это функция чтения / ограничение.

Есть ли способ прочитать STDIN, чтобы избежать этой проблемы?

РЕДАКТИРОВАТЬ

Тестовый пример: создайте демонстрационный файл. Этот символ будет иметь ~ 4k "=", за которым следует "foo bar".

 { printf '=%.0s' {1..4095} ; echo "foo bar" ; } > test.in 

Скопируйте это в свой буфер обмена

 xclip test.in 

(если вы хотите щелкнуть средним нажатием) или

 xclip -selection clipboard test.in 

(если вы хотите использовать Ctrl-Shift-Insert, чтобы пройти его)

Затем cat >test.out , вставьте (в зависимости от способа). Нажмите Ctrl-D, чтобы завершить поток. cat test.out – вы видите «foo bar»?

На моей настройке (Ubuntu 12.04, Gnome Terminal, zsh), когда я вставляю, я вижу только = и я не вижу foo bar . То же самое, когда я проверяю test.out .

Если я правильно понял источник, то в Linux максимальное количество символов, которые можно читать за один раз на терминале, определяется N_TTY_BUF_SIZE в источнике ядра. Значение 4096.

Это ограничение интерфейса терминала, в частности канонический («приготовленный») режим, который обеспечивает чрезвычайно грубый редактор строк (backspace, enter, Ctrl + D в начале строки для конца файла). Это происходит полностью за пределами процесса, который читается.

Вы можете переключить терминал в режим raw, который отключает обработку строк. Он также отключает Ctrl + D и другие тонкости, нанося дополнительную нагрузку на вашу программу.

Это древнее ограничение Unix, которое никогда не было исправлено, потому что мало мотивации. Люди не входят в такие длинные очереди. Если вы подавали входные данные из программы, вы перенаправляете ввод своей программы из файла или канала.

Например, чтобы использовать содержимое буфера обмена X, pipe из xsel или xclip . В твоем случае:

 xsel -b >file.svg xclip -selection clipboard >file.svg 

Удалите -b или -selection clipboard чтобы использовать выбор X (тот, который задан путем выделения с помощью мыши), а не буфер обмена.

В OSX используйте pbpaste для вставки содержимого буфера обмена (и pbcopy для его установки).

Вы можете получить доступ к буферу X через SSH, если вы активируете переадресацию X11 с помощью ssh -X (которую некоторые серверы могут запретить). Если вы можете использовать ssh без пересылки X11, вы можете использовать scp , sftp или sshfs для копирования файла.

Если вставка является единственным решением, потому что вы не можете пересылать буфер обмена или вы не вставляете, но, например, при вводе текста в виртуальную машину, альтернативный подход заключается в кодировании данных в нечто новое. Base64 хорошо подходит для этого: он преобразует произвольные данные в печатные символы и игнорирует пробелы при декодировании. Этот подход имеет дополнительное преимущество в том, что он поддерживает произвольные данные во входных и даже управляющих символах, которые терминал интерпретирует при вставке. В вашем случае вы можете кодировать содержимое:

 xsel -b | base64 | xsel -b 

затем декодируйте его:

 base64 -d
 Вставить
 Ctrl + D

Предел, в котором вы работаете, – это максимальный размер строки в режиме канонического ввода , MAX_CANON .

В режиме канонического ввода драйвер tty предоставляет базовые услуги редактирования строк, поэтому программе пользовательского пространства не нужно. У него не так много функций, как readline, но он распознает несколько настраиваемых специальных символов, таких как стирание (обычно Backspace или Delete) и kill (обычно Ctrl-U).

Что наиболее важно для вашего вопроса, канонические буферы режима вводятся до тех пор, пока не появится символ конца строки. Поскольку буфер находится в драйвере tty, в памяти ядра он не очень большой.

Вы можете отключить канонический режим с stty cbreak или stty -icanon , а затем сделать свою пасту. Это имеет существенный недостаток, что вы не сможете отправить EOF с помощью Ctrl-D. Это еще одна из тех вещей, за которые отвечает канонический режим. Вы все равно сможете прервать cat с помощью Ctrl-C, потому что сигнальные символы управляются отдельным флагом ( stty raw или stty -isig ).

Тайна для меня – вот почему, поскольку вы уже продемонстрировали, что знаете о xclip , вы не просто используете xclip -o > file вместо cat

cat будет принимать любое количество символов, как вы могли бы cat /dev/random > test.bin например, cat /dev/random > test.bin (не делайте этого, если не знаете, как его остановить :). Я попытался скопировать и вставить большой файл в cat > test.txt . Все строки попали в файл, был ли я отменен с помощью Ctrl- c или Ctrl- d , но в первом случае не все строки были напечатаны на терминале . Это я считаю потому, что cat буферизирует его печать, ожидая полного буфера текста или прямого ввода от терминала перед каждой печатью.

В моей системе, я думаю, размер буфера составляет 4096 (2 ^ 12) байтов: создайте файл из 4095 байтов, используя (printf '1234567890%.0s' {1..409} && printf 12345) > test.in , загрузите это в буфер копирования, используя xclip test.in , start cat > test.out , вставьте с помощью ShiftInsert и завершите поток, нажав Ctrl- d . Теперь добавьте байт, используя printf '6' >> test.in , и поток будет напечатан дважды : один раз в выходе cat (все 4096 байт) и последние 4095 байт снова в оболочке после завершения.

Если вы это сделаете:

 stty eol = 

А затем запустите демонстрацию, предложенную в вашем EDIT , вы увидите foo bar в распечатке test.out . Линейная дисциплина терминала будет очищать свой вывод до считывателя, когда он считывает каждый специальный символ eol на вашем входе.

Терминал канонического режима Linux, который может быть настроен с помощью stty icanon или, возможно, просто stty sane – обрабатывает следующие специальные символы ввода …

  • ВФ
    • default: ^D
    • Завершает вводную строку и выводит вывод на считывающее устройство. Поскольку он удаляется из ввода, если он вводится как единственный символ в строке, он передается читателю в виде нулевого чтения или конца файла .
  • EOL
    • default: unsassigned
    • Также завершает входную строку, но не удаляется из ввода.
  • убийство
    • default: ^U
    • Стирает весь буферный вход.
  • стирать
    • default: ^H (или, возможно, @ или ^? на некоторых системах)
    • Стирает последний буферный входной символ.

Когда iexten также установлен – как stty icanon iexten или, опять же, вероятно, просто stty sane , канонический Linux-терминал также будет обрабатывать …

  • EOL2
    • default: unassigned
    • Также также завершается ввод строки, а также не удаляется из ввода.
  • WERASE
    • default: ^W
    • Стирает последнее буферизованное входное слово .
  • rprnt
    • default: ^R
    • Перепечатывает весь буферный ввод.
  • СИМВОЛ
    • default: ^V
    • Устраняет любое особое значение, если речь идет о линейной дисциплине для сразу следующего входного символа.

Эти символы обрабатываются путем удаления их из входного потока – за исключением eol и eol2 , то есть – и выполнения связанной специальной функции перед передачей обработанного потока читателю, который обычно является вашей оболочкой, но может быть тем, что группа процессов переднего плана ,

Другие специальные символы ввода, которые аналогичным образом обрабатываются, но могут быть настроены независимо от любых настроек icanon, включают набор isig – set, подобный stty isig и, вероятно, также включается в разумную конфигурацию:

  • уволиться
    • default: ^\
    • Сбрасывает все буферизованные входные данные (если noflsh не задано) и отправляет SIGQUIT в группу процессов переднего плана – вероятно, генерирует ядро-дамп.
  • сусп
    • default: ^Z
    • Сбрасывает весь буферный ввод (если noflsh не установлен) и отправляет SIGTSTP в группу процессов переднего плана. kill -CONT "$!" группа процессов может быть возобновлена ​​с помощью kill -CONT "$!" или просто fg в оболочке ( set -m ), управляемой заданием.
  • ВВЕДЕНИ
    • default: ^C
    • Сбрасывает весь буферный ввод (если noflsh не установлен) и отправляет SIGINT в группу процессов переднего плана.

И ixon set – сконфигурирован как stty ixon а также обычно включается в разумную конфигурацию:

  • стоп
    • default: ^S
    • Останавливает весь вывод на считыватель до тех пор, пока ни один из них не начнет считываться на входе, или – когда ixany также установлен – считывается хотя бы один символ.
  • Начало
    • default: ^Q
    • Перезапускает выход, если он был ранее остановлен с остановкой .
  • Обе остановки и старта удаляются из ввода при обработке, но если выход перезапускается из-за любого символа на входе, когда ixany установлен, этот символ не удаляется.

Специальные символы, обрабатываемые на других системах, отличных от Linux, могут включать в себя …

  • промывать
    • default: ^O
    • Включает сброс и сброс буферизованного ввода и удаляется с входа.
  • DSUSP
    • default: unassigned
    • Сбрасывает все буферизованные входные данные только тогда, когда считыватель считывает назначенный специальный входной символ, а затем отправляет SIGTSTP.

И возможно …

  • swtch
    • default ^@ (что означает \0 или NUL )
    • Переключает передние слои оболочки. Для использования с приложением shl shell-layers в некоторых системах.
    • Реализация shl которая мультиплексирует pty и, следовательно, совместима с управлением заданиями, а не с зависимостями зависимостей от swtch от исходной реализации, может быть свободно реализована в heirloom-toolchest инструментов набора heirloom-toolchest инструмента.

Для более четкого представления о том, как и почему (и, возможно, почему нет), эти функции ввода обрабатываются с помощью man 3 termios .

Все вышеуказанные функции могут быть назначены (или переназначены) – если применимо – как function assigned-key stty . Чтобы отключить любую функцию, выполните function stty ^- . В качестве альтернативы, поскольку различные попытки присвоений для любой из вышеупомянутых функций редактирования строк со всеми реализациями STY GNU, AST или styl, как представляется, указывают, вы можете также stty function ^@ поскольку назначение NUL для любой функции, похоже, приравнивается к ее установке для непривязанного в моей Linux-системе.

Вероятно, вы видите эхо этих символов, когда вы вводите их (как может быть настроено w / [-] ctlecho ) , но это только маркер, который показывает вам, где вы это сделали – программа, получающая ваш вход, не имеет понятия, что вы набрал их (за исключением eol [2] , то есть) и получает только копию вашего ввода, к которой линейная дисциплина применила свои эффекты.

Следствием обработки терминалом различных функций редактирования строк является то, что он должен в некоторой степени буферизовать входные данные, чтобы действовать на функции, которые вы ему указываете, и поэтому не может быть безграничной подачи ввода, который вы можете в любое время убить . Буфер строк более точно является буфером уничтожения .

Если вы установите символы eol или eol2 на какой-либо разделитель, который встречается во входном файле – даже если ни одна из них не является символом новой строки или символом возврата, например, то вы сможете убить только до того момента, когда она была последней, и ваш буфер-убийца будет расширяться насколько возможно до следующего из них – или новой строки (или возврата, если icrnl установлен, а ignark – нет) – встречается во входе.