2016-08-05 65 views
3

我正在編寫一個bash腳本,該腳本從文件讀取。從文件中讀取後,我想提示用戶輸入,並從終端讀取。如何在bash中的文件輸入和終端輸入之間切換

這裏是我的代碼摘錄:

while IFS=',' read -r a b c 
do 
    #a, b, c are read in from file 
    data1=$a 
    data2=$b 
    data3=$c 

    #later in the loop 
    #answer should be read in from the terminal 
    echo "Enter your answer to continue:" 
    read answer 

done 

不過,目前我覺得劇本認爲我試圖從相同的輸入文件ab,並canswer閱讀。如何在文件和終端輸入之間切換?

+1

stdin不是命令行輸入;編輯以引用「終端輸入」。 –

+1

(「命令行輸入」意味着參數實際上放在你程序的命令行中,如'./yourprogram「第一個答案」「第二個答案」「第三個答案」) –

+0

@CharlesDuffy好的呼叫,我改變了它在問題 –

回答

4

如果你的標準輸入已經從一個文件重定向(也就是你./yourscript <file被調用的),然後使用/dev/tty從終端讀取:

#!/bin/bash 

exec 3</dev/tty || { 
    echo "Unable to open TTY; this program needs to read from the user" >&2 
    exit 1 
} 

while IFS= read -r line; do # iterate over lines from stdin 
    if [[ $line = Q ]]; then 
    echo "Getting input from the user to process $line" >&2 
    read -r answer <&3 # read input from descriptor opened to /dev/tty earlier 
    else 
    echo "Processing $line internally" 
    fi 
done 

如果你想通過跳過exec 3</dev/tty起來頂(開放/dev/tty只是一次在腳本的開頭,允許從TTY讀取以後與<&3完成),那麼你可以代替寫:

read -r answer </dev/tty 

...每次你想從終端讀取時打開它。但是,對於在循環中這些場合失敗的情況,您希望確保具有錯誤處理功能(例如,如果此代碼是從cron作業運行的,則將ssh命令與命令作爲參數傳遞並且沒有-t,或者類似的情況,其中否TTY)。


或者,考慮比其他標準輸入一個描述符打開你的文件 - 在這裏,我們使用的文件描述符#3文件輸入,並承擔調用爲./yourscript file(:標準輸入指向終端):

#!/bin/bash 
filename=$1 

while IFS= read -r line <&3; do # reading file contents from FD 3 
    if [[ $line = Q ]]; then 
    echo "Getting input from the user to process $line" >&2 
    read -r answer # reading user input by default from FD 0 
    else 
    echo "Processing $line internally" >&2 
    fi 
done 3<"$filename" # opening the file on FD 3 
+1

始終富有洞察力,並且總是將一些掘金添加到bash工具箱中。 –

+0

使用<&3效果最好,感謝您的幫助 –