![Cron 작업은 7일이 지난 모든 파일을 삭제합니다. -exec rm -f {} \;](https://linux55.com/image/200712/Cron%20%EC%9E%91%EC%97%85%EC%9D%80%207%EC%9D%BC%EC%9D%B4%20%EC%A7%80%EB%82%9C%20%EB%AA%A8%EB%93%A0%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EC%82%AD%EC%A0%9C%ED%95%A9%EB%8B%88%EB%8B%A4.%20-exec%20rm%20-f%20%7B%7D%20%5C%3B.png)
.txt
7일이 지난 파일을 삭제하기 위해 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
파일이나 디렉터리의 이름을 바꿀 수 있습니다. 따라서 다음과 같습니다.
- 루트 실행
find . -type f -user joe -exec rm -f {} \;
find
./this/
사용자가 소유한 일부 파일이 들어 있는 디렉터리를 실행하고 찾습니다.joe
- 다른 사용자가 이름을 바꾸고
./this
같은 이름으로 다른 곳을 가리키는 심볼릭 링크를 만듭니다. find
Run 을 실행하고rm -f ./this/hello.txt
이제 심볼릭 링크를 따라가세요.
hello.txt
이제 사용자뿐만 아니라 누구나 소유할 수 있으며 joe
이는 find
시작 이후에도 마찬가지이며 root
심볼릭 rm
링크 반대편에 있는 파일을 행복하게 삭제합니다. 이것은 고전이다TOCTTOU(사용 시간 확인 시간) 취약점.
더 나쁜 예를 들 수도 있지만 이는 일반적인 생각입니다.
or 를 사용하면 디렉토리 이름이 바뀌더라도 -delete
열린 파일 설명자가 여전히 동일한 디렉토리를 가리키기 때문에 이런 일이 발생하지 않습니다 . -execdir
런타임은 작업 디렉터리를 해당 디렉터리로 설정하고(시스템 호출은 다시 이름 조회 없이 파일 설명자를 통해 작업 디렉터리를 변경함), 마찬가지로 포함 디렉터리와 관련된 이름을 제거(사용)합니다.find
./this
-execdir
rm
fchdir()
-delete
unlinkat()
기본적으로(즉, 이 -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에서.