2017-04-14 48 views
3

我在編寫bash腳本時遇到了問題。我被要求寫一個可以用兩種方式調用的腳本,讀取文件或讀取標準輸入。但是,當我使用一段時間閱讀時,我不能再讀取標準輸入。這裏是我的代碼:讀取文件或讀取標準用戶輸入

#!/bin/bash 
FILE=$1 
while read LINE; 
do 
    echo "$LINE" | tr " " "\n" | tr "\t" "\n" 
done < $FILE 

回答

3

的問題來自於事實,你總是給$文件作爲輸入到你的閱讀。 當你有參數時,你可以試着將文件重定向到通道0,否則將其保留爲標準輸入。

#!/bin/bash 
FILE=$1 
if [ ! -z "$FILE" ] 
then 
    exec 0< "$FILE" 
fi 
while read LINE 
do 
    echo "$LINE" | tr " " "\n" | tr "\t" "\n" 
done 

exec 0< "$FILE"告訴shell使用$文件作爲輸入作爲通道0提醒:默認read偵聽到通道0

0<是這裏的關鍵,其中0表示信道0和<指示此是一種輸入。當沒有參數時,exec 0< "$FILE"將調用而不是,在這種情況下,通道0將使用stdin。

+0

對了工具,我傾向於說「通道0」,但對猛砸確切的詞是「文件描述符0」 。你可以用下面的命令檢查當前的fd0:'lsof -a -p $$ -d0' – vdavid

+0

感謝哥們,我只是做了一些關於這種語言的進一步研究,現在仍然是一個noob:P。 –

2

UNIX工具按照慣例使用特殊文件名-來指示輸入來自stdin。您可以調整如下:

file="${1}" 
if [ "${file}" = "-" ] ; then 
    file=/dev/stdin # special device for stdin 
fi 

while read -r line ; do 
    do something 
done < "${file}" 

現在你可以這樣調用

tool -    # reads from terminal 
cmd | tool -  # used in a pipe 
tool /path/to/file # reads from file 
+0

感謝您的回答,我會嘗試一下,並進一步研究bash。我仍然是這種語言的開端:) –

+0

同意'''通常被視爲標準輸入。但是應該避免使用'/ dev/stdin',因爲在很多情況下它不能按預期工作。通過強制使用'-'腳本不能從管道讀取。 – vdavid

+0

在某些情況下,賦值'file = $(