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を使用する必要はありません。
      • 複数の出力フィールドを並べ替える必要なく、必要な数字を要求できます。コメントの作成者は、1つはwith、trもう1つはwithを提供しましたawk。ここに2行の出力を結合し、数字ではなくすべてを削除するwithがありますseddf --output=pcent / | sed 'N;s/[^[:digit:]]//g'
  3. 工事を放棄してくださいelse :。これは:、else式構文内のコマンドに必要な場所を埋める「noop」ですが、そこでは何もしないため、else式はまったく使用されません。

  4. fiif構造を閉じるために1つがありません。

  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ファイル。

関連情報