tar 파일의 ForLoop [닫기]

tar 파일의 ForLoop [닫기]

디스크 공간을 확인한 다음 디스크 사용량 비율에 따라 조치를 취하는 스크립트를 작성하려고 합니다. 임계값이 초과되면 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

  1. 수학 방정식에 사용할 숫자를 나타내는 문자열을 인용해서는 안 됩니다. 이를 숫자로 취급하고 코드가 숫자를 그렇게 처리하는지 확인하십시오.

  2. 처음부터 올바른 형식으로 원하는 결과를 얻을 수 있다면 결과 후처리에 너무 많은 노력을 낭비하지 마세요.

    • 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'
  3. 공사를 포기하세요 else :. 이는 :else 표현식 구문에서 명령에 필요한 위치를 채우는 "noop"이지만 거기에서는 아무 것도 수행하지 않으므로 else 표현식이 전혀 사용되지 않습니다.

  4. fiif 구조를 닫는 데 하나가 누락되었습니다 .

  5. 선호의 문제이지만 들여쓰기와 제어 구조가 같은 줄에 있는지 여부를 좀 더 규칙적으로 사용한다면 구문 오류가 발생할 때 덜 혼란스러울 것입니다.

  6. if연관된 변수 사이에 변수 할당이 갇혀 있습니다 do. 실행하려는 루프의 일부이기 때문에 그 뒤에 와야 합니다.

  7. 잘못된 이름으로 변수를 호출하지 마세요. 변수가 복수형이면 복수형 이름을 지정합니다. 파일 목록인 경우 "dir"이라고 부르지 마세요. 이런 종류의 문제로 인해 코드가 실행되는 것을 막지는 못하지만, 이해하고 디버깅하기가 더 어려워지고 코드가 어디로 가는지 혼란스러울 것입니다.

  8. 인용된 변수에 쉘 전역 모드를 넣지 마십시오. for 루프를 통해 확장되도록 해야 합니다. 이렇게 하면 따옴표와 같은 이상한 내용이 포함된 파일 이름을 이스케이프 처리하는 모든 수고를 덜 수 있습니다.

  9. 단일 괄호 대신 bash의 이중 괄호 테스트 구문을 사용하면 빈 문자열과 같은 것에 더 친숙합니다.

  10. $Bash 변수를 참조할 때 접두사를 사용해야 합니다.

  11. 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파일.

관련 정보