읽기 전에 명확한 stdin


14

다음 bash 스크립트가 있습니다.

# do some time consuming task here
read -p "Give me some input: " input

짐작 하셨겠지만, "시간이 걸리는 작업"중에 사용자가 임의의 키를 누르면 원하지 않는 입력도 고려됩니다. stdinread 명령을 실행하기 전에 어떻게 지우 거나 최소한 무시합니까?


1
저주와 같은 프로그램을 작성하지 않는 한, 나는 당신이 프로그램의 디자인 결함이되기를 원하는 것을 발견합니다. UNIX / Linux는 버퍼링 입력 ( "type-ahead")의 매우 유용한 기능을 가지고 있으며 일반적으로이 기능을 사용합니다. 내가 입력 한 것을 버리는 곳에서 프로그램을 방문하면 버그를 제출하고 수정 될 때까지 프로그램 사용을 중단합니다.
— Arcege

1
일부 사용자는 키보드를 사용하여 피아노를 연주하는 성가신 습관이 있습니다. 차라리 키 입력을 버리고 새로 시작합니다. 그러나 당신이 옳습니다. "미리 입력"은 유용하지만 항상 그런 것은 아닙니다.
— rabin

답변:


8

stdin을 지우는 방법이 없다고 생각하지만 (bash와 함께) 입력을 요청하기 전에 무엇이 있는지 읽고 버릴 수 있습니다.

#do some time consuming task here
read -t 1 -n 10000 discard 
read -p "Give me some input: " input

이것은 stdin을 읽고 시간 초과가 1 초이며 stdin에 10000자를 초과하면 실패합니다. nchars 매개 변수를 얼마나 크게 만들 수 있는지 모르겠습니다.


나는 실제로 포럼에서이 핵을 발견했다. 나는 그것을하는 더 좋은 방법을 찾을 것으로 기대했다. 분명히 아닙니다.
— rabin

@ rabin : 여기에 다시 게시하는 더 좋은 방법을 찾으면 몇 가지 스크립트로 작성했습니다.

불행히도 이것은 모든 쉘에서 작동하지 않습니다 (예 : dash :(
— scai

20

Bash 4에서는 -t(timeout)을로 설정할 수 있습니다 0. 이 경우 read대기중인 데이터가 있는지 여부를 나타내는 종료 상태와 함께 즉시 반환됩니다.

# do some time consuming task here
while read -r -t 0; do read -r; done
read -p "Give me some input: " input

6
read -d '' -t 0.1 -n 10000

사용자가 실수로 여러 번 Enter 키를 누르면 여러 줄의 입력을 읽습니다.


5

이것은 나를 위해 잘 작동했습니다 :

function clean_stdin()
{
    while read -e -t 0.1; do : ; done
}

-e이 경우 왜 ?
— nhed

@nhed 더 이상 확실하지, 아마 시스템 특정 문제를 피하기 위해
— pschichtel

4

시간이 많이 걸리는 작업을 stdin이 닫힌 블록으로 묶습니다.

{
     # time consuming task
} <&-

read -p "Give me some input: " input

나는 이것이 질문과 관련이 없다고 생각합니다.
— Scott

그러나 그렇습니다! 사용자는 모든 입력을 폐기하기를 원합니다. 입력을 허용하지 않으면 stdin이 닫히기 때문에 모든 입력이 시스템에 의해 삭제됩니다. 그의 문제에 대한 우아한 해결책입니다. 그는 폐기 루프를 작성하는 데 어려움없이 시스템이 폐기를 수행하도록합니다.
— HiTechHiTouch

이것은 지금까지 가장 안정적인 옵션 인 것 같습니다.
— Stephen Eilert

완벽 해 보이지만 저에게는 효과가 없습니다. bash 5.0.0 및 4.4.19를 시도했습니다. 작업 read중에 입력 한 첫 번째 줄을 계속 읽습니다 # time consuming. 또한 스크립트에 stdin 다음에 읽은 명령이 포함되어 있지 않으면 스크립트가 종료 된 read후 읽지 않은 행이 대화식 터미널에서 실행됩니다. 누구든지 이것을 성공적으로 테스트 했습니까?
— Socowi

4

christophjaeger의 대답을 바탕으로 -s입력이 터미널에 에코 -n되지 않고 새로운 라인을 기다리지 않도록 추가했습니다.

while read -r -t 0; do
    read -n 256 -r -s
done

사용 -n하는 것이 좋지만 이전의 두 답변에서 이미 언급했습니다. 그리고이 연습의 요점 은 실행 되기 전에 입력 된 모든 것을 읽고 버리는 것이므로 , 나는 당신이 어떻게 할 것이라고 생각하는지 이해하지 못합니다 . read -s
— Scott

2
function clear_stdin()
(
    old_tty_settings=`stty -g`
    stty -icanon min 0 time 0

    while read none; do :; done 

    stty "$old_tty_settings"
)

clear_stdin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.