Shell作爲子進程啓動cat
。輸出重定向(>
)被該子進程作爲其stdout(文件描述符1)繼承。由於子進程在創建時必須繼承文件描述符,因此在啓動子進程之前,shell必須打開輸出文件。
因此,shell會打開build/3d-tags.js
進行寫入。此外,由於您沒有追加(>>
),因此會截斷該文件。請記住,這發生在cat
甚至已啓動之前。此時,由於build/3d-tags.js
的原始內容已經消失,並且cat
尚未推出,因此無法實現您想要的內容。
然後,當啓動cat
時,它會打開其參數中指定的文件。它打開它們的時間和順序並不是非常重要。當然,它可以讓他們閱讀。然後它從src/license.txt
讀取並寫入其標準輸出。寫這篇文章去build/3d-tags.js
。此時,該文件中的只有內容,因爲它之前被截斷。
cat
然後從build/3d-tags.js
讀取。它找到剛剛寫在那裏的內容,這是貓先前從src/license.txt
讀取的內容。它將該內容寫入文件的末尾。它然後回去並嘗試閱讀更多。當然,它會發現更多需要閱讀的內容,因爲它只是在文件末尾寫入更多數據。它讀取這些剩餘的數據並將其寫入文件。並繼續。
爲了cat
工作,因爲你希望(甚至忽略了殼重定向磨滅的build/3d-tags.js
內容),它會讀取和保存在內存中build/3d-tags.js
的全部內容,不管它有多大,,使它可以在寫入src/license.txt
的內容之後編寫它。
可能達到你想要什麼,最好的辦法是這樣的:
cat src/license.txt build/3d-tags.js > build/3d-tags.js.new && mv build/3d-tags.js.new build/3d-tags.js || rm -f build/3d-tags.js.new
那就是:將兩者連接起來的文件到一個新的文件;如果成功,則將新文件移動到原始文件名(替換原始文件);如果任一步驟失敗,請刪除臨時的「新」文件,以免遺留垃圾。
很酷,感謝您的詳細回覆。我很感激。這是我第一次看到邏輯或在shell腳本中使用(不是我做了很多shell腳本)! – 2014-09-30 05:10:01