パイプコマンドが期待どおりに動作しません。説明が必要です。

パイプコマンドが期待どおりに動作しません。説明が必要です。

私は以下を試しています

touch ~/scratches/scr6.txt | cat ~/scr.txt > ~/scratches/scr6.txt | cat /dev/null > ~/scr.txt

scr6.txtが常に空である理由はわかりませんが、次のようにするとファイルがいっぱいになります。

cat ~/scr.txt > ~/scratches/scr6.txt

最初のケースがなぜ機能しないのか疑問に思います。

答え1

各ステップを細分化すると、次のようになります。

  • touch ~/scratches/scr6.txt

    ファイルが存在する場合は、タイムスタンプを今すぐ更新します。存在しない場合は作成してください。

  • cat ~/scr.txt > ~/scratches/scr6.txt

    ~/scr.txt を読み、内容を ~scratches/scr6.txt に書き込みます。

  • cat /dev/null > ~/scr.txt

    ~/scr.txt ファイルの消去

コメントで述べたように、コマンドの間に「|」(PIPE)の代わりに「&&」(AND)を使用する方が適切です。

答え2

scr.txtいいですね。ファイルにいくつかのテキストが含まれており、コマンドを実行する前にまだ存在しないことを考慮すると、次のようになりますscr6.txt

touch ~/scratches/scr6.txt | cat ~/scr.txt > ~/scratches/scr6.txt | cat /dev/null > ~/scr.txt
  1. 空のscr.txtファイル( cat /dev/null > ~/scr.txt)
  2. (なし)コンテンツでscr6.txt()上書きscr.txtcat ~/scr.txt > ~/scratches/scr6.txt
  3. scr6.txtすでに存在するので何もしない(touch ~/scratches/scr6.txt

ただし、次のコマンドは

cat ~/scr.txt > ~/scratches/scr6.txt

scr.txt内容だけを書いてくださいscr6.txt

そのため、最初のケースでは両方のファイルが空ですが、2番目のケースではすべてが期待どおりに機能します。

答え3

私が理解したように、パイプラインプロセスはほぼ同時に始まります。通常、パイプのプロセスはstdinから読み取るか、stdoutに書き込みます(またはその両方)。 I / Oが完了すると、プロセスが終了するタイミングが決まります。

touch出力(例:)や標準入力(catファイル操作時など)がないプロセスの場合、通常プログラムはパイプ接続を無視することを期待します。

したがって、基本的に3つのコマンドが並列に実行されます。

touch ~/scratches/scr6.txt、、、 cat ~/scr.txt > ~/scratches/scr6.txtそしてcat /dev/null > ~/scr.txt

~/scr.txt がまだ存在しない場合、コマンド 2 がエラーで失敗するかどうかは、コマンド 3 と競合状態にあるため、オペレーティング システムによって異なります。コマンド1と2も競合状態にありますが、レースはファイルのctime / mtime / atimeにのみ影響します。

答え4

簡単に言うと:

このtouchコマンドは新しいものを生成する方法です。空のファイル。また、既存のファイルとディレクトリのタイムスタンプ(つまり、最後のアクセスと変更日時)を変更するためにも使用されます。

最初のコマンドではscr6.txt

ただし、2番目のコマンドはファイルを作成し、すべてをそのファイルscr6.txtに書き込みます。scr.txt

関連情報