rcmdnk's blog
Last update

Shell Programming in Unix, Linux and OS X: The Fourth Edition of Unix Shell Programming (4th Edition) (Developers Library)

シェルスクリプトを書いたりするときに ファイルを初期化する方法がいくつかあるのでそれについて。

Sponsored Links

ファイルの初期化

ファイルがあってもなくてもまっさらにしたい場合。

  • rm & touch

一番最初に思いつく方法

rm -f file && touch file
  • :コマンド

:は何も実行しない、という意味。 結果、何も出力されないがファイルに上書き出力するので初期化される。

: > file

echo -nとかでも同じことが出来ますが、何もしない分コストが低い。

  • /dev/nullをコピーする

空状態(/dev/null)をコピーして渡す。

cp /dev/null file

上の3つくらいがあります。

2番目のやつが一番すっきりするので好きです。

ただ、ちょっと注意が必要なのは1番目と下2つはちょっと意味が違います。

最初のものだけinode情報が変わります。 関連して下の2つの場合には最終アクセス時間が変わりません。

初期化時のタイムスタンプ

Unixのタイムスタンプには

  • atime: 最後に利用した時間(Last Accessed Time)
    • lessvimなどで中身にアクセスした時間
    • ls -luで見れる
  • mtime: 最後に変更した時間(Last Modified Time)
    • 内容が変更された時刻
    • ls -lで見れる一番良く使う時間
  • ctime: 最後にInode情報が変更された時間(Last Changed Time)
    • ls -lcで見れる
  • btime: 生成された時間(Birth Time)

という4つの種類があります。最後のbtimeはファイルシステムによってある場合とない場合があって、 MacなどBSD系では持っていることがあります。

ls以外ではstatコマンドを使うとこれらの時間を見ることが出来ます。 Linux(GNU)/BSD版でオプションに違いがあり、それぞれ以下の様な感じ。

  • Linux: stat --print="inode: %i\natime: %x\nmtime: %y\nctime: %z\nbtime: %w\n" file
  • BSD: stat -f "inode: %i%natime: %Sa%nmtime: %Sm%nctime: %Sc%nbtime: %SB%n" file

ちょっと上のファイル初期化を調べてみます。

  • OS: CentOS7(Linux(GNU)), File system: XFS

      $ rm -f file
      $ touch file
      $ stat --print="inode: %i\natime: %x\nmtime: %y\nctime: %z\nbtime: %w\n" file
      inode: 517357892
      atime: 2019-07-10 12:44:32.787391000 +0900
      mtime: 2019-07-10 12:44:32.787391000 +0900
      ctime: 2019-07-10 12:44:32.787391000 +0900
      btime: -
      $ rm -f file && touch file
      $ stat --print="inode: %i\natime: %x\nmtime: %y\nctime: %z\nbtime: %w\n" file
      inode: 517357939
      atime: 2019-07-10 12:44:55.917324000 +0900
      mtime: 2019-07-10 12:44:55.917324000 +0900
      ctime: 2019-07-10 12:44:55.917324000 +0900
      btime: -
      $ : > file
      $ stat --print="inode: %i\natime: %x\nmtime: %y\nctime: %z\nbtime: %w\n" file
      inode: 517357939
      atime: 2019-07-10 12:44:55.917324000 +0900
      mtime: 2019-07-10 12:45:03.543701000 +0900
      ctime: 2019-07-10 12:45:03.543701000 +0900
      btime: -
      $ cp /dev/null file
      $ stat --print="inode: %i\natime: %x\nmtime: %y\nctime: %z\nbtime: %w\n" file
      inode: 517357939
      atime: 2019-07-10 12:44:55.917324000 +0900
      mtime: 2019-07-10 12:45:08.872161000 +0900
      ctime: 2019-07-10 12:45:08.872161000 +0900
      btime: -
    
  • OS: macOS 10.14.5, File system: APFS

      $ rm -f file
      $ touch file
      $ stat -f "inode: %i%natime: %Sa%nmtime: %Sm%nctime: %Sc%nbtime: %SB%n" file
      inode: 50833941
      atime: Jul 10 12:40:58 2019
      mtime: Jul 10 12:40:58 2019
      ctime: Jul 10 12:40:58 2019
      btime: Jul 10 12:40:58 2019
      $ rm -f && touch file
      $ stat -f "inode: %i%natime: %Sa%nmtime: %Sm%nctime: %Sc%nbtime: %SB%n" file
      inode: 50833952
      atime: Jul 10 12:41:10 2019
      mtime: Jul 10 12:41:10 2019
      ctime: Jul 10 12:41:10 2019
      btime: Jul 10 12:40:58 2019
      $ : > file
      $ stat -f "inode: %i%natime: %Sa%nmtime: %Sm%nctime: %Sc%nbtime: %SB%n" file
      inode: 50833952
      atime: Jul 10 12:41:10 2019
      mtime: Jul 10 12:41:28 2019
      ctime: Jul 10 12:41:28 2019
      btime: Jul 10 12:40:58 2019
      $ cp /dev/null file
      $ stat -f "inode: %i%natime: %Sa%nmtime: %Sm%nctime: %Sc%nbtime: %SB%n" file
      inode: 50833952
      atime: Jul 10 12:41:10 2019
      mtime: Jul 10 12:41:59 2019
      ctime: Jul 10 12:41:59 2019
      btime: Jul 10 12:40:58 2019
    

ちょっと日時の出力表記が違いますが、Macの方だけbtimeが出ています。 (stat -t "%Y-%m-%d %H:%M:%S" -f...とすればGNUと同じ様な表記にできます。ただし、少数秒は出ません。)

両方共rm -f && touchを使った場合にはinodeが変化してbtime以外すべて変化しています。 :>cpの場合はatimeが変化しません。

ということでもしatimeとかまで気にするようなスクリプトを組んでる場合には気にしないといけない部分ですが、 通常は見てもmtimeだと思うのでそれほど気にするとこではありません。 一応知っておくと良いかと。

スクリプト的にはスッキリするので:>が好きですが、 やはり最初のrm使うのがわかりやすいといえばわかりやすいです。

追記: 2019/07/11

追記ここまで

Sponsored Links
Sponsored Links

« Dellマシンで暗躍するSmartByteを止めた Unixファイルのタイムスタンプについて »