ファイル名に基づいてファイル作成日時を変更する

ファイル名に基づいてファイル作成日時を変更する

メインサーバーからSamba共有にAsterisk通話録音をコピーしていますが、作成日時が現在の日時に変更されました。

ファイル形式は次のとおりです。in-xxxxxxxxxx-xxxxxxxxxx-20211020-162749-1634761669.7921917.wav

太い部分はEPOCH時間です。このような数百のファイルがあり、ファイル名のEPOCHタイムスタンプに基づいてファイルの作成日を変更する必要があります。誰が私を助けることができますか?

ベストアンサー1

GNU では、次の設定をtouch使用できます。touch -d @1634761669.7921917 file最後の修正指定されたエポック時間でファイルを生成します(以下に示すように、1秒未満の精度でも可能です)。

だからあなたはこれを行うことができますzsh

#! /bin/zsh -
ret=0
for file in *-<->.<->.wav; do
  t=${file:r} t=${t##*-}
  touch -d @$t -- $file || ret=$?
done
exit $ret

もしそうなら作成時間、よく呼ぶ出生時間ls -l --time=birth、最新バージョンのGNUで報告されているように、例えばls変更したい場合、私が知っている限り、Linuxでは時計をその時間に戻してファイルを再生成する以外には不可能です。


下の部分は間違った内容ですが、本当ですいいえもともと思ったように名前空間の時間を変更すればいいです。バラより@Busindreからの返信もっと学ぶ。

ただし、Linux(最新バージョン1)では、システムクロックにグローバルに影響を与えないように、新しい「タイム」ネームスペースでのみクロックを変更できます。

たとえば、次のようになります。

sudo unshare --time sh -c 'date -s @1634761669.7921917 && exec cp -a file file.new'

file.newコピーを作成します。file出生時間似たような@1634761669.7921917

$ sudo unshare --time sh -c 'date -s @1634761669.7921917 && exec cp -a file file.new'
$ ls -l --time=birth --time-style=+%s.%N file file.new
-rw-r--r-- 1 stephane stephane 0 1642699170.474916807 file
-rw-r--r-- 1 stephane stephane 0 1634761669.792191700 file.new

上記のスクリプトは次のzshように書くことができます。

#! /bin/zsh -
ret=0
for file in *-<->.<->.wav; do
  t=${file:r} t=${t##*-}
  
  unshare --time sh -c '
    date -s "@$1" && exec cp -aTn -- "$2" "$2.new"' sh "$t" "$file" &&
    mv -f -- "$file.new" "$file" || ret=$?
done
exit $ret

(そしてで実行する必要がありますroot)。

これを再び訪れたとき、いくつかのことがもっと気に入りました。

私はこれが潜在的な問題につながるということに気づきました。unshare --timeハッカーは、出生時間を過去の任意の時間に設定することができますが、これにより状態時間の変更(例:報告された時間ls -lc)は、過去の指定された時間にコピーの作成にかかった時間を加えた値に設定されます。

それ時間任意に設定できるという意味ではありません。このように過去に設定すると、一部のソフトウェアがこれらのファイルに対して作成できる仮定を破ることができます。たとえば、バックアップソフトウェアは、そのctimeが最後のバックアップ時間よりも速いため、それを無視することを決定できます。

したがって、ctimeがその名前空間で偽の時計時間に設定されていないことを確認するのが最善です。作るファイルを貼り付けて現在の内容をコピーします。

unshare --time sh -Cc '
  umask 77 && date -s "@$1" && : > "$2.new"' sh "$t" "$file" &&
  cp -aT -- "$file" "$file.new" &&
  mv -f -- "$file.new" "$file"

¹ Linux カーネル 5.6 以降が必要で、CONFIG_TIME_NSカーネル 2.36 以降で有効になっています。util-linux

おすすめ記事