2016-06-22 59 views
3

用於處理一行bash的行的文本文件,我通常執行while循環是這樣的:如何便攜式逐行讀取文本文件一行在bash

function doSomething() { 
    local inputFile="$1" 
    local fd="" 
    local line="" 
    exec {fd}<"$inputFile" # open file 
    echo "Opened ${inputFile} for read using descriptor ${fd}" 
    while IFS='' read -r -u $fd line || [[ -n "$line" ]]; do 
     echo "read = \"$line\"" 
    done 
    exec {fd}<&- # close file 
    return 0 
} 

這個工作對我的Linux,但遺憾的是沒有在OSX中。對於OSX我現在必須更改代碼以這樣的事:

exec 3<"$inputFile" # open file 
while IFS='' read -r -u 3 line || [[ -n "$line" ]]; do 
    echo "read = \"$line\"" 
done 
exec 3<&- # close file 

但是其缺點,我有我自己管理的文件描述符號(在第一個腳本,我讓bash中選擇可用文件描述符號碼)。

有人有一個適用於Linux和OSX的解決方案嗎?

注意,出於某種原因,我不想用管道或I/O重定向到像這樣完整的循環(因爲我不想在不同的進程來執行環路):

while IFS='' read -r line || [[ -n "$line" ]]; do 
    echo "read = \"$line\"" 
done < "$inputFile" 
+2

最後一個循環不會分叉一個新進程。 – PSkocik

+2

自動生成的文件描述符出現在Bash 4.1中。 OS X使用古董版本的Bash(3.something)。所以這個問題是關於跨版本的可移植性,而不是跨系統。 –

+2

但bash不是Posix shell。你將在bash版本和Posix shell的其他實現(如BSD之一)上存在可移植性問題。堅持標準的重定向,它是可移植的,不分叉子進程。 –

回答

3

最後一個循環不會分叉新的進程。您可以通過在循環內外打印"$BASHPID"來驗證。

僅爲管道創建新進程。簡單重定向在bash過程中由臨時dup處理。

隨意使用標準stdin/stdout重定向。它不會比使用內置的exec進行的重定向更昂貴。