karistin / ksh

0 stars 0 forks source link

How to set VMIN / VTIME ? #16

Closed karistin closed 2 years ago

karistin commented 2 years ago
#!/usr/bin/env python
import termios
import sys
import os
from copy import deepcopy

def get_ch():
    fd = sys.stdin.fileno()
    new = termios.tcgetattr(fd)
    sav = deepcopy(new)
    new[3] &= ~termios.ECHO
    new[3] &= ~termios.ICANON
    new[6][termios.VMIN] = 0
    new[6][termios.VTIME] = 1
    # print(new[6])
    termios.tcsetattr(fd, termios.TCSADRAIN, new)
    try:
        while(True):
            c = sys.stdin.read(1)
            sys.stdout.write(c)
            # print(c)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, sav)

get_ch()

https://man7.org/linux/man-pages/man3/tcflow.3.html 이 문서에서 MIN == 0, TIME > 0 로 설정시 read with timeout 이 설정되서 읽고 일정시간후 넘어가야 되는데 sys.stdout.write(c)가 작동하지 않습니다. 오직 print(c) 가 설정되어야 작동되는데 이는 enter가 포함되어서 인것 같습니다. 문자를 입력하는 즉시 출력을 설정하고 싶은데 어떤 부분을 고쳐야 되나요?

https://docs.python.org/ko/3/library/termios.html 여기서 VMIN / VTIME 에 설정에 대한 내용에서 정수로 정의하라고 있기에 정수로 적었습니다

Luavis commented 2 years ago

이건 우선 while True가 있어서 그런데 무한 루프로 뛰다 보니 계속 읽고 빈문자 쓰고 읽고 빈문자 쓰는 일을 계속 해서 그럼 image 위에 같이 sys.stdout.write(output+c)로 바꿔서 쓰고 ctrl+c를 누르면 termios 설정이 이전 설정으로 바뀌면서 터미널에 값이 나오는걸 알 수 있음.

그리고 경험상 echo 모드가 아니면 write해도 화면에 write가 안됨

이거는 아래 코드로 확인 가능함

#!/usr/bin/env python
import termios
import sys
import os
import time
from copy import deepcopy

def get_ch():
    fd = sys.stdin.fileno()
    new = termios.tcgetattr(fd)
    sav = deepcopy(new)
    new[3] &= ~termios.ECHO
    termios.tcsetattr(fd, termios.TCSANOW, new)
    try:
        sys.stdout.write('output')
        time.sleep(1000)
    finally:
        termios.tcsetattr(fd, termios.TCSANOW, sav)

if __name__ == '__main__':
    get_ch()

입력 받는 즉시 출력하고 싶으면 blocking read 를 쓰는게 맞고 read를 받고 나면 echo 모드를 풀어줘야만 정상출력이 될 것