Cron 작업은 7일이 지난 모든 파일을 삭제합니다. -exec rm -f {} \;

Cron 작업은 7일이 지난 모든 파일을 삭제합니다. -exec rm -f {} \;

.txt7일이 지난 파일을 삭제하기 위해 cron 작업을 실행하고 싶습니다 . 두 가지 명령이 있습니다. 첫 번째 명령:

/usr/bin/find /var/www/example.com/wp-content/targetdir -name "*.txt" -type f -mtime +7 -exec rm -f {} \;

두 번째 명령:

/usr/bin/find /var/www/example.com/wp-content/targetdir -name "*.txt" -type f -mtime +7 -delete

.txt두 명령 모두 7일이 지난 파일을 삭제하는 데 사용할 수 있습니다 . 첫 번째 명령이 다음과 같다고 읽었습니다 race condition. 첫 번째 명령보다 두 번째 명령을 사용하면 어떤 이점이 있는지 자세히 설명해 주시겠습니까? 다른 것보다 하나를 사용하는 것의 장점과 단점은 무엇입니까?

답변1

제가 본 대회는 다음과 같습니다.Stefan Chazeras의 검토또 다른 문제:

-exec rm {} +존재하지 않는 경쟁 조건 취약점이 (있는 경우) 있음을 참고하세요 . -delete따라서 다른 사람이 쓸 수 있는 디렉토리에는 사용하지 마십시오. 일부 조사 결과는 이러한 취약점을 완화할 수도 있습니다 -execdir.

실제로 는 이 부분이 보이지 않지만 (*) 거기의 경쟁은 -exec rm파일의 전체 경로가 어떻게 전달되는지와 관련이 있어 그 과정에서 트리가 다시 순회하게 된다는 것을 알 수 있습니다 rm.

find트리를 순회하고 명령줄에 제공된 조건을 평가한 후 rm다시 트리를 순회하지만 주어진 조건에 대해 알지 못하므로 find지금은 확인하지 않습니다. -delete및 를 사용하여 트리를 탐색 -execdir하고 find지정된 검사를 수행한 다음 파일을 삭제하고 항상 디렉터리의 파일 설명자를 열어 둡니다.

find파일이나 디렉터리의 조건이 평가되는 시간과 실행되는 시간 사이에 누군가 개입하여 rm파일이나 디렉터리의 이름을 바꿀 수 있습니다. 따라서 다음과 같습니다.

  1. 루트 실행find . -type f -user joe -exec rm -f {} \;
  2. find./this/사용자가 소유한 일부 파일이 들어 있는 디렉터리를 실행하고 찾습니다.joe
  3. 다른 사용자가 이름을 바꾸고 ./this같은 이름으로 다른 곳을 가리키는 심볼릭 링크를 만듭니다.
  4. findRun 을 실행하고 rm -f ./this/hello.txt이제 심볼릭 링크를 따라가세요.

hello.txt이제 사용자뿐만 아니라 누구나 소유할 수 있으며 joe이는 find시작 이후에도 마찬가지이며 root심볼릭 rm링크 반대편에 있는 파일을 행복하게 삭제합니다. 이것은 고전이다TOCTTOU(사용 시간 확인 시간) 취약점.

더 나쁜 예를 들 수도 있지만 이는 일반적인 생각입니다.

or 를 사용하면 디렉토리 이름이 바뀌더라도 -delete열린 파일 설명자가 여전히 동일한 디렉토리를 가리키기 때문에 이런 일이 발생하지 않습니다 . -execdir런타임은 작업 디렉터리를 해당 디렉터리로 설정하고(시스템 호출은 다시 이름 조회 없이 파일 설명자를 통해 작업 디렉터리를 변경함), 마찬가지로 포함 디렉터리와 관련된 이름을 제거(사용)합니다.find./this-execdirrmfchdir()-deleteunlinkat()

기본적으로(즉, 이 -L옵션이 없으면) find디렉토리 트리를 탐색할 때 발견된 심볼릭 링크는 따르지 않습니다. rm이는 기본 시스템 호출에 경로만 전달되고 평소대로 심볼릭 링크를 따르기 때문에 여기서는 도움이 되지 않습니다 . 이는 대체되는 디렉토리( ./this위)가 Symlink(또는 다른 디렉토리)로 대체되는 실제 디렉토리여야 하며, Symlink가 다른 심볼릭 링크로 대체되는 것이 아니라는 것을 의미합니다.

(*) 이 게시물을 쓴 지 20분 후에 Stéphane의 답변(아래 링크)에동일한 인종 문제를 설명하는 GNU 매뉴얼 링크. (한숨을 쉬다.)


-delete암시 -depth및 제조된 문제는 -prune그것과 아무 관련이 없으며 경쟁 조건이 아닙니다. 이것은-delete 옵션을 사용하여 검색하면 /save/ 디렉터리의 파일이 삭제되지만 삭제 옵션 없이 검색하면 해당 파일을 찾지 못하는 이유는 무엇입니까?GNU coreutils에서 find오류 메시지를 받은 것 같습니다:

$ find a -name foo -prune -o -name hello.txt -delete
find: The -delete action automatically turns on -depth, but -prune does nothing when -depth is in effect.  If you want to carry on anyway, just explicitly use the -depth option.

또 다른 차이점은 어느 정도 보편적으로 지원되더라도 -exec rm -f -- {} +표준 도구가 아닌 표준 도구만 사용한다는 점이다. -delete예를 들어 FreeBSD와 GNU는 이를 지원하지만 Busybox는 지원하지 않습니다. 바라보다:검색: "-exec rm {};" 대 "-delete" - 전자가 널리 권장되는 이유는 무엇입니까?superuser.com에서.

관련 정보