당신이 겪고있는 문제는 '원시', '요리'와 'CBREAK'모드 사이의 차이이다. 그리고이 모드들은 커널 레벨 터미널 드라이버의 모드이며, 어플리케이션 코드의 모드 나 표준 라이브러리 또는 사용자 공간의 다른 모드는 아닙니다.
쿠킹 모드에서 터미널 드라이버 자체에는 기본 라인 편집 기능이 내장되어 있습니다. 백 스페이스, 단어 지우기 (기본적으로 전체 단어를 한 번에 백 스페이스) 및 유사한 작업을 처리합니다. 화살표 키나 역사 등을 다루는 것과 같은 정교한 것은 없습니다. 매우 원시적입니다. 이 모드에서, 프로그램은 줄 끝 문자 (eol)가 전송 될 때까지 터미널에서 아무 것도 볼 수 없으며, 프로그램이 전체 줄을 가져오고 줄 끝은 Unix 표준 \n
으로 변환됩니다. 실제로 않습니다. 또한, 이것의 일부로서, 터미널 드라이버는 타이핑 된 문자를 다시 터미널에 에코하여 사용자는 타이핑하는 것을 볼 수 있습니다.
'요리'모드에서 커널 수준 터미널 드라이버는 일부 출력 변환도 수행합니다. 그리고 필요한 경우 \n
을 \r\n
으로 바꾸고 있습니다.
또한 '끝내기'모드에서 터미널 드라이버는 Control-C와 같은 특수 문자를 처리합니다 (제어 프로세스 그룹 (CPython에 의해 KeyboardInterrupt 예외로 변환 됨)에 SIGINT를 보냄) 및 Control-Z (SIGTSTP SIGSTOP, 그러나 잡힐 수 있음)을 제어 프로세스 그룹에 전달).
'cbreak'모드에서는 줄 편집이 더 이상 수행되지 않습니다. 터미널 드라이버는 각 문자 (또는 화살표 키의 이스케이프 시퀀스와 같은 짧은 문자 시퀀스)를 프로그램에 즉시 제공합니다. 이러한 문자는 화면에 표시되지 않으므로 프로그램에서 인쇄하지 않으면 사용자가 볼 수 없습니다. 터미널 드라이버는 백 스페이스 또는 단어 지우기 문자 (일반적으로 Control-W)와 같은 라인 편집 문자를 처리하지 않지만 Control-C 및 Control-Z와 같은 특수 문자를 여전히 처리합니다.또한 일부 출력 처리가 여전히 수행되므로 드라이버는 \n
을 \r\n
으로 바꿉니다.
'원시'모드에서는 입력 또는 출력에서 처리가 수행되지 않습니다. 특수 문자 처리, 에코 처리, 변형 없음 \n
을 \r\n
에 입력하고 Control-Z에 대한 처리가 없습니다. 터미널을 원시 모드로 설정하면 모든 것을 처리 할 수 있습니다.
이제 의 속성을 설정하면 sys.stdout
에 영향을주지 않아야한다고 생각할 수 있습니다. 그러나 실제로 파일 기술자 모두가 터미널 드라이버의 정확한 '인스턴스'로 이어집니다. 그리고 그것은 무슨 일이 일어나는지를 결정하는 터미널 드라이버의 설정입니다. 따라서이 설정을 sys.stdin
, sys.stdout
또는 sys.stderr
을 통해 변경하면 모두 동일한 기본 터미널 드라이버 인스턴스가 변경되고 다른 모든 설정에도 영향을줍니다.
물론 이것은 프로그램을 시작하기 전에 셸에서 리디렉션 된 파일 설명자에는 해당되지 않습니다.
지금까지 이것이 올바른 것으로 보입니다. 나는 Linux에서'\ r'을 수동으로 삽입해서는 안된다는 인상을 받고있었습니다. 고마워요 –
@ halex 원시 모드에서 이것이 정확히 필요하지만 왜 정상적으로 인쇄되지 않는지 설명 할 수 있습니까? 감사. – Stefan