파일을 자동으로 터치하는 쉘 스크립트

파일을 자동으로 터치하는 쉘 스크립트

디렉토리의 모든 파일에 액세스하는 쉘 스크립트를 작성했습니다 /tmp. 그런데 '라는 오류 메시지가 뜹니다 /bin/touch: Argument list too long. 문제의 원인은 무엇입니까?

#!/bin/bash

dayNo=1
while test $dayNo -le 200
do
    touch `find /tmp/`
    sleep 86000
done

답변1

/tmp파일이 너무 많습니다.적합하지 않음명령줄에 모든 이름을 한 번에 표시합니다(경로에 공백이 있으면 사용 중인 버전도 안전하지 않습니다).

좋은 소식은 find다음과 같이 안전하고 정확하게 수행할 수 있다는 것입니다.

find /tmp -exec touch -c '{}' +

모든 파일은 이전과 마찬가지로 찾은 다음 touch필요한 만큼 실행하여 매번 필요한 만큼의 파일을 실행합니다.

find-exec옵션일치하는 파일을 실행하고 경로를 바꾸는 명령을 수락합니다 {}. +즉, 여러 파일에 대해 한 번에 또는 각 파일에 대해 한 번씩 명령을 실행합니다 \;.touch


의견에서 지적했듯이, -execdir touch -c '{}' \;이는 엄격하게 더 안전하지만 단일 사용자 시스템에서는 약간 느리고 큰 이점이 없습니다. 먼저 각 하위 디렉터리로 전환한 다음 매번 해당 디렉터리의 파일에 대해서만 명령을 실행하여 특정 경쟁 조건을 방지합니다. 이 -execdir옵션은 비표준 확장이지만 지원됩니다.암소 비슷한 일종의 영양,FreeBSD,오픈BSD,네트워크BSD, 그리고운영 체제 finds; 다른 상용 Unices에는 일반적으로 이 기능이 없습니다. 무엇을 사용하고 있는지 잘 모르겠지만 해당되는 경우 위의 내용을 고려하세요.

답변2

쉘은 역따옴표 안의 표현식 결과를 해당 행으로 대체합니다. 그러나 시스템에는 명령 매개변수 목록의 길이에 대한 제한이 있습니다. 따라서 /tmp에 수천 개의 파일이 있으면 수천 개의 이름을 인수로 사용하여 명령을 생성하려고 시도합니다. 이것은 실패했습니다.

이 작업을 보다 쉽게 ​​수행할 수 있는 방법에는 여러 가지가 있습니다. 검색 자체에서 명령을 실행할 수 있습니다. 대부분의 최신 버전에서는 분할하여 touch각각 제한이 있는 여러 개별 명령을 실행할 수 있습니다.

find /tmp -exec touch {} +

답변3

질문에서 백틱 호출의 주요 문제점은 먼저 find 명령이 /tmp 아래의 모든 파일을 나열한 다음 해당 (거대한) 목록이 인수로 전달된다는 것입니다. touch이는 단일 호출에 너무 많은 것입니다. 파일 이름에 공백, 줄 바꿈, 세미콜론, 앰퍼샌드, 파이프 문자 또는 유사한 문자가 포함되어 있는 경우에도 문제가 발생할 수 있습니다.

다음 구조를 사용하는 것이 더 좋습니다.

find /tmp -type f -exec touch -c '{}' +

find명령은 재귀적으로 나열됩니다 /tmp.

-type f일반 파일만 선택하도록 find에 지시

-c옵션을 사용하면 touchTouch가 존재하지 않는 파일을 생성하는 것을 방지할 수 있습니다.

예제에서 몇 가지 논리를 생략한 것처럼 보이지만 200번만 수행하려는 경우 다음을 시도해 볼 수 있습니다.

#!/bin/bash

일수=1
$dayNo -le 200 테스트 시
하다
    /tmp -type f -exec touch -c '{}' + 찾기
    수면 86000
    일수=$(식 1 + ${일수})
완벽한

관련 정보