래핑하지 않고 터미널에서 4k 이상의 입력을 어떻게 읽을 수 있습니까?

래핑하지 않고 터미널에서 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- '푸바'를 보셨나요?

내 설정( Ubuntu 12.04, Gnome Terminal, zsh)에서 붙여넣을 =foo bar.test.out

답변1

소스 코드를 올바르게 이해한다면 Linux에서 터미널이 한 번에 읽을 수 있는 최대 문자 수는 다음과 같이 결정됩니다.N_TTY_BUF_SIZE커널 소스 코드에서. 이것4096입니다.

이는 터미널 인터페이스의 제한 사항입니다. 특히표준("요리") 모드이는 매우 조잡한 줄 편집기(백스페이스 키, Enter 키, Ctrl+ D파일 끝을 나타내는 줄 시작 부분)를 제공합니다. 그것은 읽기 과정 밖에서 완전히 발생합니다.

터미널을 원시 모드로 전환하여 라인 처리를 비활성화할 수 있습니다. 또한 프로그램에 추가 부담을 주는 Ctrl+ 및 기타 세부 사항 도 비활성화됩니다 .D

이는 전력 부족으로 인해 수정되지 않은 오래된 Unix 제한 사항입니다. 인간은 그렇게 긴 줄을 서지 않습니다. 프로그램에서 입력을 제공하는 경우 파일이나 파이프에서 프로그램 입력을 리디렉션할 수 있습니다.

예를 들어, X 클립보드의 내용을 사용하려면 파이프를 사용하세요.xsel또는xclip. 귀하의 경우:

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

클립보드 대신 삭제 -b하거나 X 선택(마우스 강조로 설정된 선택)을 사용하세요.-selection clipboard

OSX에서는 다음을 사용하세요.pbpaste클립보드 내용을 붙여넣고 pbcopy설정합니다.

X11 전달(일부 서버에서는 비활성화될 수 있음)을 활성화하면 ssh -XSSH를 통해 X 클립보드에 액세스할 수 있습니다. sshX11 포워딩 없이 만 사용할 수 있는 경우 scp, sftp또는 를 사용하여 sshfs파일을 복사할 수 있습니다.

클립보드를 전달할 수 없거나 붙여넣지는 않지만 가상 머신에 대한 입력을 위조하기 때문에 붙여넣기가 유일한 솔루션인 경우, 또 다른 접근 방식은 데이터를 줄 바꿈을 사용하여 무언가로 인코딩하는 것입니다.Base64이에 적합합니다. 임의의 데이터를 인쇄 가능한 문자로 변환하고 디코딩할 때 공백을 무시합니다. 이 접근 방식은 입력 시 임의의 데이터를 지원하며, 붙여넣을 때 터미널이 해석하는 제어 문자도 지원한다는 추가 이점이 있습니다. 귀하의 경우 콘텐츠를 인코딩할 수 있습니다.

xsel -b | base64 | xsel -b

그런 다음 디코딩하십시오.

base64 -d
  Paste
Ctrl+D

답변2

발생한 제한은 행의 최대 크기입니다.표준 입력 모드, MAX_CANON.

표준 입력 모드에서 tty 드라이버는 기본적인 줄 편집 서비스를 제공하므로 사용자 공간 프로그램에서는 이 작업을 수행할 필요가 없습니다. readline만큼 많은 기능은 없지만 삭제(보통 백스페이스 또는 삭제) 및 종료(보통 Ctrl-U)와 같은 일부 구성 가능한 특수 문자를 인식합니다.

귀하의 질문에 대한 결론은 표준 모드가 줄 끝 문자를 볼 때까지 입력을 버퍼링한다는 것입니다. 버퍼는 tty 드라이버, 커널 메모리에 있기 때문에 그다지 크지 않습니다.

stty cbreak표준 모드를 ​​사용하거나 끈 stty -icanon다음 붙여넣을 수 있습니다. 이는 Ctrl-D를 사용하여 EOF를 보낼 수 없다는 중요한 단점이 있습니다. 이는 정식 패턴이 담당하는 또 다른 사항입니다. cat신호 생성 문자는 별도의 플래그( stty raw또는 stty -isig) 에 의해 제어되므로 여전히 Ctrl-C를 사용하여 종료할 수 있습니다 .

나에게 미스터리는 왜 당신이 알고 있다는 것을 증명했기 때문에 단지 사용 xclip하지 않는가 하는 것입니다.xclip -o > filecat

답변3

이렇게 하면:

stty eol =

그런 다음 제안된 데모를 실행하십시오.편집하다, 당신은 볼 것이다풍부한 바인쇄물에서확인해 보세요. 터미널의 줄 규칙은 각 특수 문자를 읽을 때 출력을 판독기로 플러시합니다.단종입력한 문자입니다.

Linux 정식 모드 터미널 - 구성할 수 있거나 다음과 같은 특수 입력 문자를 처리 stty icanon할 수도 있습니다 ...stty sane

  • 에브
    • 기본:^D
    • 입력 라인을 종료하고 출력을 판독기로 플러시합니다. 입력에서 제거되기 때문에 한 줄의 유일한 문자로 입력되면유효하지 않은읽기 - 또는파일 끝- 독자 여러분께.
  • 단종
    • 기본값: 할당되지 않음
    • 또한 입력 행을 종료하지만 입력에서 제거하지는 않습니다.
  • 죽이다
    • 기본:^U
    • 버퍼링된 입력을 모두 지웁니다.
  • 삭제
    • 기본:^H (또는 어쩌면 @또는 ^?일부 시스템에서)
    • 마지막 버퍼링된 입력 문자를 지웁니다.

언제확장하다또한 설정하십시오 - stty icanon iexten또는 다시 말하지만 stty sane표준 Linux 터미널도 처리할 것입니다...

  • 단종 2
    • 기본값: 할당되지 않음
    • 반품반품입력 라인을 종료하고반품입력에서 제거되지 않습니다.
  • 베르세
    • 기본:^W
    • 마지막 버퍼링된 입력 지우기단어.
  • 회전수
    • 기본:^R
    • 버퍼링된 모든 입력을 다시 인쇄합니다.
  • 다음
    • 기본:^V
    • 줄 규칙에 관한 한 바로 뒤에 오는 입력 문자의 특별한 의미는 제거됩니다.

이러한 문자는 입력 스트림에서 제거하여 처리됩니다. 예외단종그리고단종 2즉, 처리된 스트림을 판독기에 전달하기 전에 관련 특수 기능을 수행합니다. 이는 일반적으로 셸이지만 모든 포그라운드 프로세스 그룹일 수 있습니다.

다른 특수 입력 문자도 유사하게 처리되지만 문자와 독립적으로 구성할 수 있습니다.이카논설정에는 다음이 포함됩니다.isig설정 - 설정은 유사 stty isig하며 다음에 포함될 수도 있습니다.합리적인구성:

  • 사직하다
    • 기본:^\
    • 버퍼링된 모든 입력 플러시(만약에짧은 이야기설정되지 않음)SIGQUIT를 전경 프로세스 그룹에 보냅니다. 코어 덤프가 생성될 수 있습니다.
  • 미결
    • 기본:^Z
    • 버퍼링된 모든 입력 플러시(만약에짧은 이야기설정되지 않음)SIGTSTP를 전경 프로세스 그룹에 보냅니다. 정지된 프로세스 그룹은 다음 방법 중 하나로 kill -CONT "$!"재개될 수 있습니다 fg.( set -m)작업 제어 쉘.
  • 정수
    • 기본:^C
    • 버퍼링된 모든 입력 플러시(만약에짧은 이야기설정되지 않음)SIGINT를 전경 프로세스 그룹에 보냅니다.

게다가익슨set - 구성은 유사 stty ixon하며 일반적으로 다음에도 포함됩니다.합리적인구성:

  • 멈추다
    • 기본:^S
    • 다음까지 리더에 대한 모든 출력을 중지합니다.시작입력을 읽거나 - 언제익사니또한 설정됨 - 하나 이상의 문자를 더 읽었습니다.
  • 시작
    • 기본:^Q
    • 이전에 출력이 중지된 경우 출력을 다시 시작합니다.멈추다.
  • 둘 다멈추다그리고시작처리하는 동안 입력에서 제거되지만 입력의 문자로 인해 출력이 다시 시작되는 경우익사니해당 캐릭터는 설정 후에도 삭제되지 않습니다.

Linux가 아닌 다른 시스템에서 처리되는 특수 문자에는 다음이 포함될 수 있습니다.

  • 플러시
    • 기본:^O
    • 버퍼링된 입력 삭제 및 플러시와 입력에서 제거를 전환합니다.
  • 덥썩
    • 기본값: 할당되지 않음
    • 모든 버퍼링된 입력은 판독기가 지정된 특수 입력 문자를 읽은 다음 SIGTSTP를 보내는 경우에만 플러시됩니다.

그리고 어쩌면...

  • 스위치
    • 기본^@ (의미 \0또는 NUL)
    • 전경 쉘 레이어를 전환합니다. 그리고 사용shl 껍데기일부 시스템의 응용 프로그램.
    • 깨달음shlpty를 재사용하므로 원래 구현이 아닌 작업 제어와 호환됩니다.스위치의존적 행동은 다음과 같이 자유롭게 발생할 수 있습니다.heirloom-toolchest도구 키트.

방법과 이유에 대한 보다 명확한 이해(어쩌면 안 될지도)이러한 입력 기능의 처리를 참조하십시오 man 3 termios.

위의 모든 기능을 할당할 수 있습니다.(또는 재할당)- 해당되는 경우 - 좋아요sttyfunction assigned-key. 개별 기능을 비활성화하려면 다음을 수행하십시오.sttyfunction^-. 또는 위의 줄 편집 기능을 GNU, AST 또는 Heirloom 구현에 배포하려는 다양한 시도에서 stty알 수 있듯이 다음을 수행할 수도 있습니다.sttyfunction^@~처럼영점어떤 기능에 할당하는 것은 그것을 다음과 같이 설정하는 것과 같습니다.할당되지 않은내 리눅스 시스템에서.

어쩌면 봤을지도 모르지에코이 문자를 입력하면(아마도 다음과 같이 구성될 수 있습니다.[-]크트레치오), 그러나 이는 귀하가 수행한 작업을 표시하는 것일 뿐입니다. 귀하의 입력을 받는 프로그램은 귀하가 입력한 내용을 알지 못합니다.(와는 별개로단종[2], 그건)Line Discipline이 효과를 적용한 입력 사본만 수신합니다.

터미널이 다양한 줄 편집 기능을 처리하는 데 따른 한 가지 결과는 수행하도록 지시한 기능을 수행하기 위해 어느 정도 입력을 버퍼링해야 한다는 것입니다. 따라서 무한한 입력 공급이 불가능합니다. 언제든지 가지고죽이다. 이것철사버퍼는 더 정확하게는죽이다완충기.

설정하면단종또는단종 2입력에서 발생하는 일부 구분 문자(예를 들어 개행 문자나 반환 문자가 아닌 경우에도)죽이다마지막으로 그 일이 일어났을 때까지 그리고 당신은죽이다버퍼는 다음 또는 개행 문자가 나올 때까지 가능한 한 확장됩니다.(또는 다음과 같은 경우 반환ICRNL설정되어 있으며소홀히 하다아니요)- 입력에 나타납니다.

답변4

한 가지 해결책은 vim과 같은 긴 줄을 지원하는 편집기에 붙여넣는 것입니다.

vim을 사용하는 경우 먼저 붙여넣기 모드로 들어간 :paste다음 삽입 모드로 들어가서 i텍스트를 붙여넣습니다.

관련 정보