스크립트

스크립트

현재 나는 완전한 수작업을하고 있습니다.

find /home/bash_cookbook/bash_cookbook/glassfish/domains/blog/logs -mtime +7 -type f -name 'application.log_*' -exec rm {} \;

탐색하려는 모든 디렉토리 이름을 입력하는 데만 한 시간이 걸렸습니다.

질문?

각 서버에는 서로 다른 도메인 이름을 가진 20개의 서로 다른 도메인이 있는 100개 이상의 서버가 있습니다. 제가 생각해낸 영리한 접근 방식은 특정 디렉토리를 모두 포함하는 대신 제외하는 것입니다. 그 중 일부에는 제가 건드릴 필요가 없는 "백업"과 같은 일부 도메인이 포함되어 있기 때문입니다.

그러나 나는 그것을 구현하는 방법을 모른다.


내가 생각할 수 있는 또 다른 멋진 트릭은 이것이다.

find /home/bash_cookbook/bash_cookbook/glassfish/domains/$domains_except_excluded_domains/logs -mtime +7 -type f -name 'application.log_*' -exec rm {} \;

이렇게 하려면 제외하려는 모든 도메인을 포함해야 하는 domains_ Except_excluded_domains 변수가 필요합니다. 이것이 어떻게 달성될 수 있습니까?

답변1

배열을 지원하는 다른 셸을 사용하는 경우 bash처리를 위해 포함할 필드 집합을 나열할 수 있습니다.

#!/bin/bash
incDomains=('blog' 'news' 'webmail' …)

for domain in "${incDomains[@]}"
do
    echo "Considering $domain"
    find "/home/bash_cookbook/bash_cookbook/glassfish/domains/$domain/logs" -mtime +7 -type f -name 'application.log_*' -delete
done
echo "Done"

$domain변수가 find경로 의 어디에 삽입되어야 하는지 추측하고 있습니다 . 필요에 따라 이동하십시오.

당신은 다음과 같은 것을 사용할 수 있습니다들어오지 못하게 하다도메인(안전하게 열거할 수 있다고 확신하는 경우) 이 방법은 제외할 도메인 목록으로 시작하여 빠른 조회를 위해 이를 연관 배열(해시)로 변환한 다음 해시의 모든 디렉터리를 건너뛰고 도메인 디렉터리 집합을 반복합니다.

#!/bin/bash
excDomains=('blog' 'news' 'webmail' …)

declare -A excDomainsH
for domain in "${excDomains[@]}"; do excDomainsH[$domain]=1; done

for domainPath in "/home/bash_cookbook/bash_cookbook/glassfish/domains"/*
do
    domain="${domainPath##*/}"
    [[ "${excDomainsH[$domain]}" -eq 1 ]] && continue

    echo "Considering $domain"
    find "$domainPath/logs" -mtime +7 -type f -name 'application.log_*' -delete
done
echo "Done"

두 경우 모두 나는추천-delete-print코드가 예상대로 작동한다고 확신할 때까지 . 구현에서 사용을 고려 find하지 않는 경우 ( 끝 참고)-delete-exec rm -f {} ++

답변2

전체 디렉터리를 제외하려면 경로를 부정적으로 일치시키는 것이 한 가지 옵션입니다.

find ! -path '*exclude1*' ! -path '*exclude2*' ...

-name와 달리 -path슬래시는 포함될 수 있으며 특별히 처리되지 않습니다.

주요 문제가 속도라면 그 이유는 너무 많은 디렉터리를 검색하는 것이 아니라 -exec rm {}\;파일당 한 번씩 호출하기 때문일 수 있습니다. rm로 바꾸면 됩니다 -delete. 또한 man find와 의 차이점에 대해서도 읽어보세요. 여기서 후자는 명령 인수 목록만큼 많은 결과를 사용합니다.-exec command {}\;-exec command {} +

답변3

이것이 이 문제에 대한 나의 시도입니다.

스크립트

#!/bin/bash
given_path=/home/techyman/glassfish4/glassfish/domains
excluded_folder=x
for each in $(ls $given_path); do
    if [ "$excluded_folder" = "$each" ]; then
        echo "This is x"
        continue
    else
        echo "this is not x"
        cd $given_path/$each/logs
        echo "This is $PWD"
    fi
done

그것이 무엇을 할 수 있는지

  • 지정된 경로로 이동합니다.
  • 목록을 작성하나요?
  • ls가 제외된 폴더와 같으면 continue 문을 사용하여 해당 폴더를 건너뜁니다.
  • 그렇지 않으면 로그 디렉터리로 이동하여 일부 작업을 수행합니다.

고쳐 쓰다:

#!/bin/bash
given_path=/home/techyman/glassfish4/glassfish/domains
excluded_folder=x
for each in "$given_path"/*; do
    if [ "$excluded_folder" = "$each" ]; then
        echo "This is x"
        echo "$PWD"
        continue
    else
        echo "this is not x"
        echo "$PWD"
        cd $each/logs
        # echo "This is $PWD"
        # echo "This is $x"
    fi
done

고쳐 쓰다

#!/bin/bash

given_path=/home/techyman/glassfish4/glassfish/domains
excluded_folder="x"
function clear_log() {
    cd "$each"
    echo "$PWD"
    find . -mtime +"$1" -name "*.log" -exec rm -f {} \;
    #echo "$2"
    #echo "$1"
}
for each in "$given_path"/*; do
    if [ "$each" = "$given_path/$excluded_folder" ]; then
        echo "$each"
        #echo "This is x"
        #echo "Do nothing"
        continue
    else
        #echo "this is not x"
        #echo "$each"
        #case statement goes here
        case $each in
        *a)

            echo "This is a"
            clear_log 7 "$each"
            ;;
        *b)
            echo "This is b"
            clear_log 4 "$each"
            ;;
        *c)
            echo "This is c"
            clear_log 5 "$each"
            ;;
        *d)
            echo "This is d"
            clear_log 6 "$each"
            ;;
        *e)
            echo "This is e"
            clear_log 8 "$each"
            ;;
        esac
    fi
done

관련 정보