디스크 공간을 확인한 다음 디스크 사용량 비율에 따라 조치를 취하는 스크립트를 작성하려고 합니다. 임계값이 초과되면 dailybackup 디렉터리에서 일부 파일을 삭제할 수 있기를 원합니다. 그러나 이 디렉터리(tar 파일)의 콘텐츠를 반복하는 것이 어렵다는 것을 알았습니다. 어떻게 할 수 있는지에 대한 아이디어가 있습니까? 현재 스크립트의 모습은 다음과 같습니다.
#!/bin/bash
#
# Drive cleanup
threshold='70'
currentDate=$(date +%F | sed 's/-//g')
currentDateClip=$(date +%F | sed 's/-//g' | cut -c 1-4)
used=$(df -h | awk '{print $4}' | sed 's/%//g' | head -3 | tail -1)
dir='~/scripts/dailybackup/*.sheldns.*'
if [ $used -ge $threshold ]
then
for FILE in $dir
local secondArg=$((basename $FILE) | cut -c 1-4)
do
if [ (expr currentDate - secondArg) -gt '400' ]
then
echo "We are good to go"
else
:
done
else
:
fi
답변1
수학 방정식에 사용할 숫자를 나타내는 문자열을 인용해서는 안 됩니다. 이를 숫자로 취급하고 코드가 숫자를 그렇게 처리하는지 확인하십시오.
처음부터 올바른 형식으로 원하는 결과를 얻을 수 있다면 결과 후처리에 너무 많은 노력을 낭비하지 마세요.
date +%F | sed 's/-//g'
공정해야 합니다date +%F%m%d
.date +%F | sed 's/-//g' | cut -c 1-4
공정해야 합니다date +%Y
(어차피 처음 4자만 잘라내기 때문에 sed가 작동하지 않는 것은 아닙니다).df -h | awk '{print $4}' | sed 's/%//g' | head -3 | tail -1
여러 면에서 단순화되어야 합니다.- 머리/꼬리 조합을 혼동하지 마십시오. 디스크 이름을 사용하여 원하는 라인을 찾을 수 있으며, 이렇게 하면 시스템에 드라이브를 추가할 때 취약성이 줄어듭니다.
- 어떤 경우든
df
드라이브 마운트 지점에 대한 정보를 요청할 수 있으므로 grep을 사용할 필요도 없습니다. - 여러 출력 필드를 정렬할 필요 없이 원하는 숫자를 요청할 수 있습니다. 한 댓글 작성자는 하나는 with ,
tr
다른 하나는 with 를 제공했습니다awk
. 여기에 두 줄의 출력을 결합하고 숫자가 아닌 모든 것을 제거하는 with 가 있습니다sed
.df --output=pcent / | sed 'N;s/[^[:digit:]]//g'
공사를 포기하세요
else :
. 이는:
else 표현식 구문에서 명령에 필요한 위치를 채우는 "noop"이지만 거기에서는 아무 것도 수행하지 않으므로 else 표현식이 전혀 사용되지 않습니다.fi
if 구조를 닫는 데 하나가 누락되었습니다 .선호의 문제이지만 들여쓰기와 제어 구조가 같은 줄에 있는지 여부를 좀 더 규칙적으로 사용한다면 구문 오류가 발생할 때 덜 혼란스러울 것입니다.
if
연관된 변수 사이에 변수 할당이 갇혀 있습니다do
. 실행하려는 루프의 일부이기 때문에 그 뒤에 와야 합니다.잘못된 이름으로 변수를 호출하지 마세요. 변수가 복수형이면 복수형 이름을 지정합니다. 파일 목록인 경우 "dir"이라고 부르지 마세요. 이런 종류의 문제로 인해 코드가 실행되는 것을 막지는 못하지만, 이해하고 디버깅하기가 더 어려워지고 코드가 어디로 가는지 혼란스러울 것입니다.
인용된 변수에 쉘 전역 모드를 넣지 마십시오. for 루프를 통해 확장되도록 해야 합니다. 이렇게 하면 따옴표와 같은 이상한 내용이 포함된 파일 이름을 이스케이프 처리하는 모든 수고를 덜 수 있습니다.
단일 괄호 대신 bash의 이중 괄호 테스트 구문을 사용하면 빈 문자열과 같은 것에 더 친숙합니다.
$
Bash 변수를 참조할 때 접두사를 사용해야 합니다.Bash 목욕 표현은 문법적이어야 합니다
$(( <expression> ))
.
이러한 모든 주석을 고려하면 스크립트는 다음과 같습니다.
#!/bin/bash
threshold=70
currentYear=$(date +%Y)
used=$(df --output=pcent / | sed 'N;s/[^[:digit:]]//g')
if [[ $used -ge $threshold ]]; then
for FILE in ~/scripts/dailybackup/*.sheldns.*; do
local fileYear=$((basename $FILE) | cut -c 1-4)
if [[ $(($currentYear - $fileYear)) -gt 400 ]]; then
echo "We are good to go"
fi
done
fi
프로세스를 더 쉽게 만들기 위해 할 수 있는 일이 더 있습니다. 예를 들어, 계산을 건너뛰고 oldDate=$(date +%Y -d '400 years ago'). This would give you a number that you could compare directly as in
[[ $fileYear -le $oldYear ]]`로 시작하는 이전 연도 날짜를 요청하면 무슨 일이 일어나고 있는지 더 쉽게 이해할 수 있습니다.
또한 이름을 구문 분석하는 대신 파일 수정 시간을 사용하여 전체 파일 반복 프로세스를 피할 수 있습니다.
#!/bin/bash
if [[ $(df --output=pcent / | tr -d "A-Za-z% \n") -ge 70 ]]; then
find ~/scripts/dailybackup/ -type f -name '*.sheldns.*' -ctime +146000 -print
fi
결과에 만족하면 찾은 파일만 삭제 -print
하도록 변경할 수 있지만 146000(400년의 일 수)을 실제로 일부와 일치할 가능성이 더 높은 값으로 줄여야 합니다. -delete
파일.