읽기 전에 명확한 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.