2012-03-16 64 views
0

我想將許可文件添加到* nix目錄和任何子目錄中的每個.java文件的前面。我有這樣的解決方案,這似乎很好地工作:爲什麼shell重定向與find發生奇怪的交互

$ cat muppet-license.txt 
// LICENSE: // Manuh-manuh 
$ for file in `find . -iname "*.java"`; do 
    cat muppet-license.txt "$file" > "$file.out"; 
    mv "$file.out" "$file"; 
done 

我的問題是,爲什麼下面找到調用不起作用:

find . -iname "*.java" -exec sh -c 'cat muppet-license.txt "$1" > "$1"' -- {} \; 

這將導致通過找到有找到的第一個文件「muppet許可證」反覆添加到它的前面 - 文件似乎不停地增長。

有人可以解釋是什麼造成了這裏的區別是?是否與修改名爲$ 1的文件有關,從而導致find將其重新找到作爲遞歸搜索的一部分?有沒有人有任何好的參考找到使用的算法的細節?

回答

3

你告訴貓,你是寫從同一文件讀取:

cat muppet-license.txt "$1" > "$1" 

所以貓會讀muppet-license.txt並將其寫入$1,然後讀$1(現在包含許可證)和追加然後繼續讀取已寫入的內容等等,然後繼續無休止地循環複製$1以內的許可證文件...

類似這樣的內容應該可以工作:

find . -iname "*.java" -exec sh -c 'cat muppet-license.txt "$1" > "$1.out"; mv "$1.out" "$1"' -- {} \; 

這寫許可和$1到一個單獨的文件$1.out和寫入之後移動回$1避免了死循環。與查找無關,只與調用sh和cat有關。

+0

我明白了。這不是我問的問題。你有沒有正確閱讀? – kittylyst 2012-03-17 01:36:09

+1

要麼你誤解了我(和其他人)的回答,要麼你需要編輯來澄清你的問題。稍微編輯我的迴應以更明確地表達意思。 – 2012-03-17 02:04:08

3

的問題是,

cat foo $file > $file 

會做的正是你告訴它做,這並不總是顯而易見的。 shell執行該命令的第一件事是打開$file進行寫入,因此將其截斷爲零長度。然後運行cat,將foo$file的內容連接起來,這些內容現在是foo的副本,並轉換爲$file

1

問題不在於找到。如果你這樣做,會發生同樣的行爲:

cat muppet-license.txt a.java > a.java 

,是因爲貓是重新閱讀它寫入數據。 shell打開a.java進行寫入,將其截斷爲零。 cat然後將muppet-license.txt的內容寫入a.java,然後打開a.java(現在是muppet-license.txt的一個副本),並將第一行寫入文件末尾(第二行線)。然後它讀取第二行並在末尾添加(寫入第3行),並連續重複。

+0

你是什麼意思?你的評論意味着什麼...... – kittylyst 2012-03-17 01:37:48

+1

@kittylyst:什麼評論?你是指我的答案嗎?你覺得我的答案如何令人困惑? shell截斷a。java,丟棄它中的所有數據。貓然後進入一個無限循環,並永不終止(直到你的文件系統已滿或發生其他錯誤)。 – 2012-03-17 02:34:22