web-dev-qa-db-ja.com

ターゲットファイルがまだ存在しない場合、 `>>`によるリダイレクトは `>`と同等ですか?

Bashやshのようなシェルを考えてみましょう。 >>>の基本的な違いは、ターゲットファイルが存在する場合に現れます。

  • >はファイルをゼロサイズに切り捨ててから書き込みます。
  • >>は切り捨てません、それはファイルの終わりに書きます(追加します)。

ファイルが存在しない場合は、サイズ0で作成されます。その後に書いた。これは両方の演算子に当てはまります。ターゲットファイルがまだ存在しない場合でも、演算子は同等であるように見えます。

彼らは本当にですか?

79

tl; dr

いいえ。>>は基本的に「常にファイルの終わりを探す」のに対し、>は最後に書き込まれた場所へのポインタを維持します。


全回答

(注:私のテストはすべてDebian GNU/Linux 9で行った)。

もう一つの違い

いいえ、それらは同等ではありません。 他に違いがあります。ターゲットファイルが以前に存在していたかどうかにかかわらず、それ自体が現れる可能性があります。

これを観察するには、データを生成し、>または>>を使用してファイルにリダイレクトするプロセスを実行します(例:pv -L 10k /dev/urandom > blob)。それを実行してファイルのサイズを変更しましょう(例えばtruncateで)。 >は常に(末尾に)追加されますが、>>は(増加する)オフセットを維持します。

  • ファイルをもっと小さいサイズに切り詰めた場合(サイズがゼロになることもあります)
    • >は気にせず、何も起こらなかったかのように希望のオフセットで書き込みます。オフセットの切り捨てがファイルの末尾を超えた直後に、ファイルは元のサイズに戻り、さらに大きくなります。不足しているデータはゼロで埋められます(可能な場合は疎な方法で)。
    • >>は新しい末尾に追加され、ファイルは切り捨てられたサイズから大きくなります。
  • ファイルを大きくすると
    • >は気にせず、何も起こらなかったかのように希望のオフセットで書き込みます。サイズが変更された直後にオフセットがファイル内のどこかにあると、オフセットが新しい端に達するまでファイルはしばらくの間増加しなくなり、その後ファイルは正常に拡大します。
    • >>は新しい末尾に追加され、ファイルはその拡大サイズから大きくなります。

別の例としては、データ生成プロセスが実行されていてファイルに書き込んでいるときに、(別の>>を付けて)余分なものを追加することがあります。これはファイルを拡大するのに似ています。

  • >を使用した生成プロセスは、必要なオフセットで書き込みを行い、最終的に余分なデータを上書きします。
  • >>を使用した生成プロセスでは、新しいデータがスキップされて追加されます(競合状態が発生し、2つのストリームがインターリーブされる可能性がありますが、データを上書きすることはできません)。

それは実際には重要ですか?この質問は あります

私は標準出力に大量の出力を生成するプロセスを実行しています。すべてをファイルに送る[...]ある種のログローテーションプログラムを使うことができますか?

この答え は、解決策はlogrotateオプション付きのcopytruncateであることを示しています。

コピーを作成した後、元のログファイルを切り捨てて、古いログファイルを移動し、必要に応じて新しいログファイルを作成します。

上記の記事によると、>を使用してリダイレクトすると、切り捨てられたログがすぐに大きくなります。まばらさは日を節約するでしょう、重要なディスクスペースは無駄にされるべきではありません。それにもかかわらず、それぞれの連続したログはそれに完全に不必要であるそれにますます多くの先行ゼロがあるでしょう。

しかし、logrotateが疎さを維持せずにコピーを作成する場合、これらの先行ゼロはコピーが作成されるたびにますます多くのディスクスペースを必要とします。私はツールの振る舞いを調べていませんが、疎かさや圧縮をその場で行っても十分に賢いかもしれません(圧縮が有効になっている場合)。それでも、ゼロはトラブルを引き起こすか、せいぜい中立である可能性があります。それらには何もありません。

この場合、ターゲットファイルがまだ作成されようとしていても、>>の代わりに>を使用する方がはるかに優れています。


パフォーマンス

お分かりのように、2人のオペレーターは、開始時だけでなく後でも異なる動作をします。これは(微妙な?)パフォーマンスの違いを引き起こすかもしれません。現時点では、それをサポートまたは反証する意味のあるテスト結果はありませんが、それらのパフォーマンスが一般的に同じであると自動的に想定するべきではないと思います。

106