현재 나는 완전한 수작업을하고 있습니다.
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