入力をファイル自体として受け取るコマンドからの出力をファイルに保存できないのはなぜですか?

入力をファイル自体として受け取るコマンドからの出力をファイルに保存できないのはなぜですか?

たとえば、私が使用しているコマンドは次のとおりです。

tr -d '\n' < newfile.ppm 

結果をまったく同じファイルに出力したいので、次のようにします。

tr -d '\n' < newfile.ppm > newfile.ppm

なぜこれが機能しないのでしょうか、また、どうすれば機能するようになるのでしょうか?

答え1

これは非常によくある「落とし穴」です。

stdout または stderr をリダイレクトしてファイルに書き込む場合、シェルは最初にファイルを切り捨てて書き込みの準備をします。つまり、おおよそ次のような処理が行われます。

  1. シェルはstdinを次のように設定しますnewfile.ppm
  2. シェルのnewfile.ppm長さは0に切り捨てられます
  3. シェルはstdoutを次のように設定しますnewfile.ppm
  4. シェルは を実行しますtr -d '\n'。 ご覧のとおり、この時点で の内容はnewfile.ppmすでに消えているので、読み取るものはありません。

これを回避するには、代わりに別のファイルに出力します。その後、名前を変更できます。

答え2

これであなたの望み通りの働きをします。

[stephan@stephan] ~ 
$ echo "meh                                    
" > file
[stephan@stephan] ~ 
$ cat file | tr -d '\n' > file ; cat file 
meh

関連情報