파일 이름을 기준으로 파일 생성 날짜 및 시간 변경

파일 이름을 기준으로 파일 생성 날짜 및 시간 변경

메인 서버에서 삼바 공유로 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)에서는 시스템 시계에 전역적으로 영향을 주지 않도록 새로운 "time" 네임스페이스에서만 시계를 변경할 수 있습니다.

예를 들어 다음과 같습니다.

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

답변2

unshare시간 네임스페이스를 잘못 사용했습니다 . 이 date명령을 사용하여 시스템 날짜와 시간을 설정하면 "CLOCK_REALTIME" 유형의 시스템 호출이 이루어집니다.

이 시스템 호출은 time 네임스페이스와 호환되지 않으므로 unshare -T운영체제 전체에 영향을 주지 않기 위해 time 네임스페이스()를 사용해도 동작하지 않는다. -T/--time 옵션과 함께 unshare를 사용하는 경우 새 네임스페이스에 적용되는 유일한 시스템 호출은 CLOCK_MONOTONIC/BOOTTIME(예제 uptime명령)입니다.

액세스 및 수정 시간을 복제하려면 touch의 -r 옵션을 사용할 수 있습니다.

touch target_file -r reference_file

관련 정보