Bash 스크립트 - 최근에 변경된 파일이 있는지 확인

Bash 스크립트 - 최근에 변경된 파일이 있는지 확인

저는 특정 디렉터리의 파일이 최근에 수정되었는지 확인해야 하는 스크립트를 작성 중입니다. 간단히 사용할 수 있다고 생각했지만 find일치하는 항목을 찾지 못하더라도 성공을 보고합니다.

$ touch afile
$ find . -mtime -1 -iname ????*
./afile
$ echo $?
0
$ find . -mtime +1 -iname ????*
$ echo $?
0

(방금 '.'을 제외하기 위해 iname 술어를 사용했지만 과 동일한 동작 -type f)

ls나는 이와 같은 출력을 구문 분석하고 싶지 않습니다 .성격이 안 좋을 수도 있어요.

을 사용하면 test -n "$(find . -mtime -1 -iname ????*)"예상한 결과를 얻을 수 있는 것 같지만 특별히 우아한 솔루션은 아닌 것 같습니다.

어떤 파일이 수정되었는지 알 필요는 없습니다. 단지 최근에 파일이 변경되었다는 것뿐입니다("가장 최근"은 일반적으로 1일임).

더 좋은 방법이 있나요?

(Google에서 검색하면 간단한 조회를 수행하는 방법에 대한 SEO 관련 헛소리가 많이 나옵니다.)

답변1

예, 보시다시피 find의 종료 코드를 사용하여 이와 같은 작업을 수행할 수 없습니다. 종료 코드는 파일이 발견되었는지 여부가 아니라 명령이 성공적으로 실행되었는지 여부에만 관련됩니다. 결국 파일을 찾지 못하는 것은 실패가 아니라 성공입니다. 파일이 없는 올바른 결과를 얻게 됩니다. 이에 man find대한 설명은 다음과 같습니다(GNU find에서 인용).

종료 상태

모든 파일이 성공적으로 처리되면 find는 상태 0으로 종료되고, 오류가 발생하면 상태는 0보다 큽니다. 이는 의도적으로 매우 광범위한 설명이지만 반환 값이 0이 아닌 경우 결과의 정확성에 의존해서는 안 됩니다.찾다.

특정 오류가 발생하면 지정된 모든 작업을 완료하지 않고 find가 즉시 중지될 수 있습니다. 예를 들어, 일부 시작점은 아직 확인되지 않았거나 일부 보류 중인 프로그램 호출이 있을 수 있습니다. -exec ... {} +또는-execdir ... {} +아직 구현되지 않았을 수 있습니다.

당신은 실제로 그것을 사용할 수 있습니다 -n $(find ...). 나는 거기에서 실제로 문제를 보지 못합니다. 파일 이름은 포함될 수 없기 때문에 NUL이것이 깨질 수 있는 상황은 생각할 수 없습니다. 좀 더 깔끔한 것을 원한다면 배열을 사용해 본 다음 배열의 요소 수가 초과되었는지 테스트할 수 있습니다 0. 이 같은:

$ findResults=( $(find . -mtime -1 -iname '????*' | head -n1) )
$ [[ ${#findResults[@]} -gt 0 ]] && echo "Found files!" || echo "No files found!"
Found files!

$ findResults=( $(find . -mtime +1 -iname '????*' | head -n1) )
$ [[ ${#findResults[@]} -gt 0 ]] && echo "Found files!" || echo "No files found!"
No files found!

그러나 솔직히 이것이 [[ -n $(find ...) ]] && echo found || echo nope.

답변2

zsh를 사용하여,

if ()(($#)) **/????*(NDY1m-1); then
  echo There are files or directories last modified within the last 24 hours
fi
  • () {body} args정의 및 실행익명 함수(($#))여기의 본문은 (매개변수 수)가 0이 아닌 경우 true를 반환하는 산술 표현식입니다.$#
  • **/모든 레벨(레벨 0 포함)의 디렉토리, Extendedglob 의 약어입니다 (*/)#. 그 자체는 고려되지 않습니다 .. 고려되기를 원하는 경우 **/로 바꿀 수 있습니다.{.,**/}
  • N: 빈 공글로벌 예선: 일치하는 항목이 없어도 불평하지 말고 익명 함수에 빈 목록을 전달하세요.
  • D: dotglob, 숨겨진 파일을 건너뛰지 마세요.
  • Y1: 최적화로 첫 번째 일치에서 중지
  • m-1: 마지막 m수정은 마지막 날(24시간)에 이루어졌습니다(예: find의 ) -mtime -1.

를 사용하면 이름이 4자 이상인 파일을 일치시키는 데 대신 set -o extendedglob사용할 수 있습니다 .?(#c4,)????*

답변3

if find . -name '????*' -mtime -1 | LC_ALL=C grep -q '^'; then
  echo There are files last modified within the last 24 hours
fi

일치하는 파일이 많으면 grep -q입력 줄을 읽은 후 종료되고 find다음에 파이프에 무언가를 쓸 때 종료되므로 약간 더 효율적일 수 있습니다.

파이프의 출력은 파이프에 들어갈 때 버퍼링 되므로 find첫 번째 파일이 발견되면 파이프가 종료되지 않습니다.

GNU 또는 FreeBSD를 사용하면 find다음을 수행할 수 있습니다.

if [ -n "$(find . -name '????*' -mtime -1 -print -quit)" ]...

NetBSD에서 이는 사소한 최적화 로 대체할 수 있는 -exitGNU 를 사용하는 것과 동일합니다 .find-print-printf .

다음을 수행할 수도 있습니다.

if [ -n "$(
  find . -name '????*' -mtime -1 -exec sh -c 'echo .; kill -s PIPE "$PPID"' ';'
  )" ]...

where find호출은 sh무언가를 출력하고 그 부모를 죽입니다.

답변4

mtree바이너리로 가득 찬 디렉터리가 악의적이거나 손상된 코드로 덮어쓰여지지 않았는지 확인하거나 파일 세트가 실수로 변경되지 않았는지 확인하려는 사용 사례(데이터 또는 메타데이터에서)와 같은 작업을 위해 특별히 설계되었습니다.

-c요약을 포함하여 목차( )에 대한 참조 파일을 생성( )합니다 .my_dir.mtree-p my_dir-K sha256

$ sudo mtree -c -p my_dir -K sha256 > my_dir.mtree

다음에 파일이 수정되었는지 확인하려면 경로 옵션과 mtree 사양 파일 mtree만 제공하여 다시 실행하세요.-p

$ sudo mtree -p my_dir < my_dir.mtree

다른 파일이 나열됩니다.

관련 정보