2015-09-06 114 views
0

嗨即時嘗試暫停進程的執行,以便用戶不能進行多個條目,直到5秒過去。我嘗試使用睡眠,但睡眠只是停下來,然後執行用戶在進程睡着時運行的所有輸入,我不希望在程序睡眠時有任何輸入讀取。Bash Unix:我怎樣才能暫停進程而不使用睡眠命令

的我想要什麼

例如:一個聊天機器人 輸入1:喜 輸出:「從程序回覆」 輸入2(5秒前是上升):「什麼新的」 -NO輸出 - 輸入 3( 5秒過去了):「你好嗎」 輸出:即時通訊罰款。什麼睡眠命令不

例如: 輸入1「喜」 輸出「哎」 輸入2(5秒前):「什麼新的」 - 沒有輸出 - 等待 輸入3:「你怎麼樣「 輸出:‘沒有多少是新的’ 輸出:‘我沒事’

+0

使用while循環並計算時間。 –

+1

請查看[editing-help](http://stackoverflow.com/editing-help)。 – Cyrus

+0

這不是一件容易的事:這裏不是你的程序,而是環境的工作方式:它緩衝輸入,直到你的程序再次接受它爲止。您可以嘗試從輸入中分離臨時文件,但最簡單的方法是實際讀取並轉儲所有輸入5秒鐘。 – arkascha

回答

1

你可以閱讀和5秒後扔掉用戶的輸入可達

# 1. 
read -p "prompt 1: " first_thing 

sleep 4 

# this reads and ignores whatever the user has typed during the sleep 
while read -t 1 _garbage; do :; done 

# 2. 
read -p "prompt 2: " next_thing 

read小號-t 1運如果沒有什麼可讀的話,則是一秒超時。

測試

  1. 與輸入

    $ read -p "prompt 1: " first_thing; sleep 4; while read -t 1 _garbage; do :;done ; read -p "prompt 2: " next_thing 
    prompt 1: foo 
    bar 
    baz 
    prompt 2: qux 
    $ echo $first_thing $next_thing 
    foo qux 
    
  2. 第二讀之前沒有 「額外」 輸入 - 過程中不 「掛」 在等待輸入

    $ read -p "prompt 1: " first_thing; sleep 4; while read -t 1 _garbage; do :;done ; read -p "prompt 2: " next_thing 
    prompt 1: hello 
    prompt 2: world 
    $ echo $first_thing $next_thing 
    hello world 
    
1

這絕非易事,而你需要更具體地說明您希望腳本如何響應鍵盤輸入。

沒有辦法「鎖定」鍵盤;用戶可以繼續按照他們認爲合適的方式打孔。如果您是內容的鑰匙要呼應,但你要輸入被忽略,你可以這樣做以下:

# Beware! Read the entire answer; don't just use this command 
timeout 5 bash -c 'while :;do read -s -d ""; done' 

timeout實用程序運行一個命令,殺死它時,指定的秒數已經過去;指定的數字可能是小數部分。圍繞read命令的循環是必需的,因爲read會在按下Enter鍵後立即終止; while :; do是「永遠循環」的標準成語。

timeout命令是Gnu coreutils的一部分。如果你沒有它,也許是因爲你正在使用BSD衍生產品,你可能會找到其他選擇。有一個FreeBSD命令,可能在其他BSD上可用,包括Mac OS X,名爲timelimit;我相信正確的調用是將timeout 5替換爲timelimit -t 5 -s9,但我沒有任何簡單的測試方法。

您需要讓read命令立即實際讀取輸入,而不是等到按下Enter鍵。否則,在終止read之後,鍵入的輸入仍然可用於下一個命令。

有幾種方法可以做到這一點。一種是使用-n 1標誌使read在每個字符後返回;另一種方法是使用-d ""將輸入字符的末尾設置爲NUL,這會將讀取置於一次一個字符模式。

此外,您可能想要抑制在讀取循環中按下的鍵的回顯。您可以通過將-s標誌添加到read命令來做到這一點,但是當read命令被中斷時,將會產生副作用,使終端處於「無回聲」模式。 [注1]

不幸的是,您可能會發現終端設置已被永久更改,因爲readtimeout命令終止時,它沒有機會恢復終端設置。所以你最終會得到一個終端,它不迴應,不處理退格和其他行編輯命令,並且不遵守Ctrl-D等問題。

爲避免此問題,您需要保存並恢復終端設置。你可以做到這一點的stty命令,如下所示:

# Save the terminal settings 
saved=$(stty -g) 
# Ignore input for 5 seconds, suppressing echo 
timeout 5 bash -c 'while :;do read -s -d ""; done' 
# Restore the terminal settings 
stty "$saved" 

  1. 如果不抑制回聲,你會發現你的輸入提示可以在同一行上出現的忽視輸入。您可避免通過輸出一個「回車/擦除結束行的」前提示控制序列:

    tput cr; tput el; read -p "Give me some input: " 
    
0

@glenn的答案是一個很好的答案!
也許你不知道前面你要睡多久(你打電話 一些其他功能)。 當你只想刷新輸入隊列時,你可以嘗試類似的方法:

echo "What is your name?" 
read name 
echo "Please be quiet for 5 seconds" 
sleep 5 

smalltime=0.000001 
read -t ${smalltime} -s garbage 
while [ -n "${garbage}" ]; do 
    echo "Flushing $garbage" 
    read -t ${smalltime} -s garbage 
done 

echo "Hello ${name}, please say something else" 
read y 
echo "You said $y"