Поэтому у меня есть много данных без новых строк в буфере обмена (это большой SVG-файл в одну строку). я пошел
$ cat >file.svg
затем попытался вставить (в Gnome Terminal), но были приняты только первые 4 КБ символы.
Я предполагаю, что это функция / ограничение readline.
Есть ли способ прочитать из 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в начале строки для конца файла). Это происходит полностью вне процесса, который читает.
Вы можете переключить терминал в необработанный режим, который отключает обработку строк. Он также отключает Ctrl+ Dи другие тонкости, накладывая дополнительную нагрузку на вашу программу.
Это древнее ограничение Unix, которое никогда не было исправлено, потому что там мало мотивации. Люди не заходят в такие длинные очереди. Если бы вы вводили ввод из программы, вы бы перенаправили ввод вашей программы из файла или канала.
Например, чтобы использовать содержимое буфера обмена X, канал из
xsel
илиxclip
. В твоем случае:Удалите
-b
или-selection clipboard
используйте выбор X (тот, который установлен выделением мышью), а не буфер обмена.В OSX используйте
pbpaste
для вставки содержимого буфера обмена (иpbcopy
для его установки).Вы можете получить доступ к буферу обмена X через SSH, если активируете переадресацию X11 с помощью
ssh -X
(которую некоторые серверы могут запретить). Если вы можете использовать толькоssh
без пересылки X11, вы можете использоватьscp
,sftp
илиsshfs
скопировать файл.Если вставка является единственным решением, потому что вы не можете переслать буфер обмена или не вставляете, а, например, имитируете ввод текста на виртуальной машине, альтернативный подход заключается в кодировании данных во что-то, что имеет символы новой строки. Base64 хорошо подходит для этого: он преобразует произвольные данные в печатные символы и игнорирует пробелы при декодировании. Этот подход имеет дополнительное преимущество, заключающееся в том, что он поддерживает произвольные данные на входе, даже управляющие символы, которые терминал будет интерпретировать при вставке. В вашем случае вы можете закодировать контент:
затем расшифруйте его:
источник
xsel
с размером > 4 Кб существует очень неприятная ошибка, связанная с повреждением данных : github.com/kfish/xsel/issues/14Предельное вы бежите в это максимальный размер строки в режиме канонического ввода ,
MAX_CANON
.В режиме канонического ввода драйвер tty предоставляет базовые сервисы редактирования строк, поэтому программа пользовательского пространства не нуждается в этом. У него не так много функций, как у readline, но он распознает несколько настраиваемых специальных символов, таких как erase (обычно 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
источник
Если вы делаете:
А затем запустите демонстрацию, предложенную в вашем редакторе , вы увидите строку foo в распечатке test.out . Линейная дисциплина терминала будет сбрасывать свой вывод в читатель, когда он читает каждый специальный символ eol в вашем вводе.
Терминал Linux в каноническом режиме - который может быть настроен
stty icanon
или, возможно, простоstty sane
- обрабатывает следующие специальные символы ввода ...^D
^U
^H
(или возможно@
или^?
в некоторых системах)Когда iexten также установлен - как
stty icanon iexten
или, опять же, вероятно, простоstty sane
, канонический терминал Linux также будет обрабатывать ...^W
^R
^V
Эти символы обрабатываются путем удаления их из входного потока - за исключением EOL и EOL2 , то есть - и выполнять соответствующую специальную функцию перед передачей обработанного потока для читателя - который, как правило , в оболочке, но может быть все , что группа процессов переднего плана ,
Другие специальные входные символы, которые обрабатываются аналогичным образом, но могут быть настроены независимо от любого параметра icanon, включают набор isig - set like
stty isig
и, вероятно, также включены в нормальную конфигурацию:^\
^Z
kill -CONT "$!"
или толькоfg
в (-set -m
) управляемой заданием оболочке.^C
И набор ixon - настроен как
stty ixon
и также обычно включается в нормальный конфиг:^S
^Q
Специальные символы, обрабатываемые в других системах, отличных от Linux, могут включать ...
^O
И возможно ...
^@
(значение\0
илиNUL
)shl
shell-layer в некоторых системах.shl
которая мультиплексирует ptys и, следовательно, совместима с управлением заданиями, а не с зависимым от swtch поведением оригинальной реализации, может свободно использоваться вheirloom-toolchest
наборе инструментов.Для более ясного представления о том, как и почему (и, возможно, почему нет) эти функции ввода обрабатываются, обратитесь к
man 3 termios
.Все вышеперечисленные функции могут быть назначены (или переназначены) - если применимо - как
stty
function assigned-key
. Чтобы отключить любую функцию, сделайте . В качестве альтернативы, поскольку различные попытки с назначениями для любой из вышеупомянутых функций редактирования строк со всеми реализациями GNU, AST или семейной реликвии, по- видимому, указывают, вы также можете, поскольку назначение NUL для любой функции, по-видимому, равносильно установке его как неназначенного в моем linux система.stty
function
^-
stty
stty
function
^@
Возможно, вы видите эхо этих символов при их вводе (что, вероятно, можно настроить с помощью [ / ] ctlecho ) , но это всего лишь маркер, показывающий, где вы работали - программа, получающая ваши данные, не имеет представления о том, что вы набрал их (исключая eol [2] , то есть) и получил только копию вашего ввода, к которому дисциплина применяет свои эффекты.
Следствием того, что терминал обрабатывает различные функции редактирования строк, является то, что ему необходимо в некоторой степени буферизовать ввод для того, чтобы воздействовать на функции, которые вы указываете ему, что он должен, - и поэтому не может быть неограниченной подачи ввода, которая Вы можете в любое время убить . Линия буфер более точно убить буфера.
Если вы установите Eol или EOL2 символы в какой - то разделитель , который происходит на входе - даже если ни один не символ перевода строки или возврата символов, например , - тогда вы будете только в состоянии убить до такой степени , что это в последний раз произошло и ваш убить буфер будет расширяться, насколько это возможно, до тех пор, пока следующая из них - или новая строка (или возврат, если icrnl установлен, а igncr - нет) - не появится на входе.
источник
cat
будет принимать любое количество символов, как вы могли бы засвидетельствовать, например,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
, запуститеcat > test.out
, вставьте с помощью Shift- Insertи завершите поток нажатием Ctrl- d. Теперь добавьте байт с помощьюprintf '6' >> test.in
, и поток будет напечатан дважды : один раз наcat
выходе (все 4096 байтов) и последние 4095 байтов снова на оболочке после завершения.источник
Одно из решений - вставить его в редактор, который поддерживает длинные строки, например, vim.
Если вы используете vim, сначала войдите в режим вставки с,
:paste
↵прежде чем войти в режим iвставки с помощью и вставить текст.источник