2012-09-01 2 views
4

파이썬에서 표준 입력을 비 - 버퍼 모드로 전환해야하므로 단일 문자를 읽을 수 있습니다. 나는 그럭저럭 작동시킬 수 있었지만 지금은 표준 출력이 깨져서 : 어떻게 든 그것은 줄 바꿈 문자 다음에 보이는 것과 같이 어떤 공백 문자가 나오고, 첫번째 줄은 0, 두번째 줄은 3, 세번째 줄은 6 등과 같다. :파이썬 원시 모드 stdin print 공백 추가

ASD 
    ASD 
     ASD 

운영 체제는 Ubuntu Linux 12.04, 64 비트 버전이며, Python 버전은 3.2.3입니다.

어떻게하면이 문제에서 벗어날 수 있습니까? 당신은 단지 라인 피드하지만 캐리지 리턴을하고있는 것처럼

import sys 
import tty 
import termios 

fd = sys.stdin.fileno() 
old_settings = termios.tcgetattr(fd) 
tty.setraw(sys.stdin) 

for i in range(0, 10): 
    print("ASD") 

termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 

답변

4

가 보이는 : 아래

내가 사용했던 코드입니다. 인쇄물을

print("ASD", end="\r\n") 
+0

지금까지 이것이 올바른 것으로 보입니다. 나는 Linux에서'\ r'을 수동으로 삽입해서는 안된다는 인상을 받고있었습니다. 고마워요 –

+0

@ halex 원시 모드에서 이것이 정확히 필요하지만 왜 정상적으로 인쇄되지 않는지 설명 할 수 있습니까? 감사. – Stefan

5

으로 변경하십시오.이 질문에 대한 답변을 검색 할 때 Google이 나를 데려 왔습니다. 아무 마차 반환의 halex에 의해 공유 된 단서는 진리에 대한 나의 수색을 도왔다. 여기 tty.py의 소스 읽어 저를 이끌어 https://utcc.utoronto.ca/~cks/space/blog/unix/CBreakAndRaw : 나는 크리스의 위키의 게시물에 내 대답을 발견 결론에 나를 데리고 https://hg.python.org/cpython/file/618ea5612e83/Lib/tty.py 을 그 목표는 대신, 하나의 문자를 읽을 경우 :

tty.setraw() 

사용 :

tty.setcbreak() 
3

당신이 겪고있는 문제는 '원시', '요리'와 '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을 통해 변경하면 모두 동일한 기본 터미널 드라이버 인스턴스가 변경되고 다른 모든 설정에도 영향을줍니다.

물론 이것은 프로그램을 시작하기 전에 셸에서 리디렉션 된 파일 설명자에는 해당되지 않습니다.