2012-03-16 13 views
0

* nixディレクトリとサブディレクトリのすべての.javaファイルの前にライセンスファイルを追加したいとします。私は正常に動作するようです。このソリューションを、持っている:シェルリダイレクトが奇妙な動作をする理由

$ 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呼び出しでは動作しません、次のとおりです。

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

これは持っていることを見つけることで見つかった非常に最初のファイルを引き起こしその上に "muppet license"が繰り返し追加されました。ファイルは停止せずに継続的に増加するようです。

ここでの違いを引き起こす原因を説明できる人はいますか? $ 1という名前のファイルを変更して再帰的検索の一部として再検索するのは何か?誰もが使用するアルゴリズムの詳細への良い参照を持っていますか?

答えて

3

あなたが書いているとあなたは同じファイルからの読み取りに猫を言っている:

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

だから、猫は(今のライセンスが含まれています)$1を読み、追加、その後、muppet-license.txtを読み、$1にそれを書き込みます同じファイルの最後に再度ライセンスを書き込んだり、書き込んだ内容を読み続けるなどして、$1のライセンスファイルを繰り返し複製していく...

このようなものが動作するはずです:

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

これは、別のファイル$1.outへのライセンスと$1を書き込み、それを書いた後$1に戻って、それを移動することによって、無限ループを回避することができます。違いはfindとはまったく関係がありません。shとcatを呼び出すだけです。

+0

私はそれを得る。それは私が尋ねたqではありません。あなたはそれを正しく読みましたか? – kittylyst

+1

私が(そして他の人たちが)答えたことを誤解したか、質問を明確にするために編集する必要があります。意味をより明確にするために、私の反応を少し編集しました。 –

3

問題が

cat foo $file > $file 

は正確にあなたが常に明白ではありませんこれは、行うには、それを教えてくれ何だろうということです。シェルがそのコマンドで最初に行うことは、書き込みのために開かれる$fileです。このため、ゼロ長に切り捨てられます。次にcatが実行され、foo$fileの内容が連結され、今fooのコピーが$fileにコピーされます。

1

問題は見つからない。

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

これは、猫が書き込んでいるデータを再度読み込んでいるためです。シェルはa.javaを書き込み用に開き、長さをゼロに切り捨てます。 catはmuppet-license.txtの内容をa.javaに書き込み、次にa.java(これはmuppet-license.txtのコピーです)を開き、ファイルの最後に第1行を書き込みますライン)。次に、2行目を読み取り、最後に追加します(3行目を書きます)。そして、連続して繰り返します。

+0

どういう意味ですか?あなたのコメントは何の意味もありません。 – kittylyst

+1

@kittylyst:どのようなコメントがありますか?私の答えに言及していますか?私の答えはどうですか?あなたは混乱していますか?シェルはaを切り詰めます。java、その中のすべてのデータを破棄します。 catは無限ループに入り、決して終了しません(あなたのファイルシステムがいっぱいになるか、他のエラーが発生するまで)。 –