これらの2つのコマンドは、ファイルのゼロ消去についてどのように異なるのですか?後者は前者を行うより短い方法ですか?舞台裏で何が起こっているのですか?
両方とも
$ cat /dev/null > file.txt
$ > file.txt
産出
-rw-r--r-- 1 user wheel 0 May 18 10:33 file.txt
cat /dev/null > file.txt
は 猫の無駄な使用 です。
基本的にcat /dev/null
は単にcat
に何も出力しない結果になります。はい、動作しますが、必要のない外部プロセスを呼び出す結果となるため、多くの人が不満を抱いています。
それが一般的であるという理由だけで一般的であるものの1つです。
> file.txt
だけを使用すると、ほとんどのシェルで機能しますが、完全に移植可能ではありません。完全にポータブルにする場合は、次の方法が適しています。
true > file.txt
: > file.txt
:
とtrue
はどちらもデータを出力せず、シェルの組み込み関数です(cat
は外部ユーティリティです)。したがって、これらはより軽量でより適切です。
更新:
タイラーが彼のコメントで述べたように、>| file.txt
構文もあります。
ほとんどのシェルには、>
を使用して既存のファイルを切り捨てないようにする設定があります。代わりに>|
を使用する必要があります。これは、実際に>>
を追加するつもりであった場合の人的エラーを防ぐためです。 set -C
で動作をオンにできます。
したがって、これを使用すると、ファイルを切り捨てる最も簡単で適切な、移植可能な方法は次のようになると思います。
:>| file.txt
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
ノート:
sh
またはksh
エミュレーションを除いて、コマンドのないリダイレクトの場合、zshではデフォルトのコマンドが想定されます(標準のリダイレクトのみのページャー、それ以外の場合はcat
)。 NULLCMDおよびREADNULLCMD変数で調整する。これは(t)csh
の同様の機能から発想を得たものです:
はコメントリーダーとnullコマンドの間の途中で解釈されたため、UnixV7では:
のリダイレクトは最初は実行されませんでした。後でそれらはすべてのビルトインと同じようになり、リダイレクトが失敗した場合、シェルを終了します。:
およびeval
は特別な組み込みであり、リダイレクトが失敗した場合、シェルを終了します(bash
はPOSIXモードでのみ実行されます)。(t)csh
では、(goto
の)nullラベルを定義しているため、goto ''
がそこに分岐します。リダイレクトが失敗した場合は、シェルを終了します。$PATH
(:
は一般に使用できない場合を除いて、true
、cat
、cp
およびprintf
は一般的にあります(POSIXではそれらが必要です)。file
が存在しないファイルへのシンボリックリンクである場合、GNUのような一部のcp
実装はそのファイルの作成を拒否します。(このセクションは非常に主観的です)
> file
。その>
は、プロンプトやコメントのように見えます。また、それを読んだときに私が尋ねる質問(そしてほとんどのシェルは同じことについて不平を言うでしょう)はどの出力を正確にリダイレクトしていますか?です。: > file
。 :
は、no-opコマンドとして知られています。つまり、空のファイルを生成するとすぐに読み取れます。ただし、ここでも、その:
は簡単に見落とされたり、プロンプトとして表示されたりする場合があります。true > file
:リダイレクトまたはファイルコンテンツとブール値はどう関係していますか?ここで何を意味するのでしょうか?それを読んだときに最初に思い浮かぶのは.cat /dev/null > file
。 /dev/null
をfile
に連結しますか?cat
は、ファイルのコンテンツをダンプするコマンドとしてよく見られますが、センス:the空のファイルの内容をfile
にダンプします。 cp /dev/null file
の複雑な表現ですが、それでも理解できます。cp /dev/null file
。 空のファイルの内容をfile
にコピーします。理にかなっていますが、cp
がデフォルトでどのように機能するかを知らない人は、file
をnull
デバイスにしようとしていると思うかもしれません。eval > file
またはeval '' > file
。何も実行せず、その出力をfile
にリダイレクトします。私には理にかなっています。それが一般的なイディオムではないことは奇妙です。printf '' > file
:明示的にprints何もファイルに出力しません。私にとって最も意味のあるもの。違いは、組み込みのシェルを使用しているかどうかです。そうでない場合、プロセスをフォークして、コマンドをロードして実行する必要があります。
eval
は、すべてのシェルでビルドされることが保証されています。 :
は、利用可能な場所に組み込まれています(Bourne/cshが好き)。 true
はBourneのようなシェルにのみ組み込まれています。
printf
は、組み込みの最新のBourneのようなシェルとfish
です。
cp
とcat
は通常、組み込みではありません。
現在、cp /dev/null file
はシェルリダイレクトを呼び出さないため、次のようになります。
find . -exec cp /dev/null {} \;
より効率的になります:
find . -exec sh -c '> "$1"' sh {} \;
(必ずしも以下ではありませんが:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
)。
個人的には、ボーンのようなシェルで: > file
を使用しており、最近ではボーンのようなシェル以外は使用していません。
あなたはtruncate
を見たいかもしれません、それはまさにそれをします:ファイルを切り捨てます。
例えば:
truncate --size 0 file.txt
これはおそらくtrue > file.txt
を使用するよりも遅くなります。
ただし、私の主なポイントは次のとおりです。truncate
はファイルの切り捨てを目的としていますが、>を使用するとファイルが切り捨てられるという副作用があります。
答えは、file.txt
が何であるか、およびプロセスがそれにどのように書き込むかによって多少異なります。
一般的なユースケースを引用します。file.txt
というログファイルが増えており、それをローテーションしたいとします。
したがって、たとえば、file.txt
をfile.txt.save
にコピーしてから、file.txt
を切り捨てます。
このシナリオでは、[〜#〜] if [〜#〜]ファイルがanother_process
によって開かれていない(例:another_process
はプログラムである可能性があります)そのファイル、たとえば何かをログに記録するプログラム)に出力する場合、2つの提案は同等であり、両方が適切に機能します(ただし、最初の「cat/dev/null> file.txt」は猫の無用な使用なので2番目が推奨されます)また、/ dev/nullを開いて読み取ります)。
しかし、実際の問題は、other_process
がまだアクティブで、file.txtへのオープンハンドルがまだある場合です。
次に、other process
がファイルを開いた方法に応じて、2つの主なケースが発生します。
other_process
がそれを通常の方法で開いた場合、ハンドルはファイル内の以前の場所、たとえばオフセット1200バイトを指しています。したがって、次の書き込みはオフセット1200から開始されるため、1200バイト(+ other_processが書き込んだもの)のファイルがあり、1200の先行ヌル文字があります。 あなたが望むものではない、私は推測します。
other_process
がfile.txt
を「追加モード」で開いた場合、書き込みを行うたびに、ポインタはファイルの最後までアクティブにシークします。したがって、それを切り捨てると、バイト0まで「シーク」し、悪影響はありません。 これはあなたが望むものです(...通常!)
これは、ファイルをトランケートするときに、その場所への書き込み中のすべてのother_process
が「追加」モードでファイルを開いていることを確認する必要があることを意味することに注意してください。それ以外の場合は、これらのother_process
を停止してから再起動する必要があるため、以前の場所ではなくファイルの先頭からポイントを開始します。
参照: https://stackoverflow.com/a/16720582/18415 より明確な説明、および https:// stackoverflow .com/a/984761/18415
見た目がすっきりしていて、誰かが誤ってReturnキーを押してしまったのではないため、私はこれが好きで頻繁に使用しています。
echo -n "" > file.txt
組み込みも必要ですか?