上記のフォルダパスを考慮して、特定の日数より古いファイルを削除するスクリプトを作成しようとしています。パスをハードコーディングするだけでなく、より高度な手法を使用しようとしています(実際の例では、さらに多くのフォルダーがあります)。これが私がこれまでに持っているものです:
#!/bin/bash
FILEAGE=15
#Array of folders to clean
dir_array=(
"/srv/*/folderA"
"/srv/level1D/*/folderA"
)
#function to be used for deleting files. Needs to be called with a path
function dir_delete() {
echo "Deleting:"
find $1 -type f -mindepth 1 -maxdepth 1 -mtime +$FILEAGE -delete -print
echo ""
}
echo "##### Looping through dir_array array and using dir_delete function to delete files older than $FILEAGE days #####"
for d in "${dir_array[@]}";do
if [ -d $d ];then
echo "##### Deleting all files older than $FILEAGE in $d #####"
dir_delete $d
else
echo "##### Did not find directory: \$d #####"
echo ""
fi
done
私のスクリプトは、次のようなディレクトリが見つからないことを返しています。
Did not find directory: /srv/*/folderA
注:15日以内に、これらのフォルダー全体に削除できないファイルがあります。
@Kusalanandaの提案を使用する'/srv/'*'/folderA'
私のためにそれを修正しました。上記の元の投稿に間違ったコードを残しているのは、誰かが私が間違っていたことを確認したい場合です。
シェルグロブパターン*
は、二重引用符で囲まれていません。これはあなたのループが
for d in "${dir_array[@]}";do
パターンをループしています。 dir_delete
の呼び出しでは、引用符で囲まれていないパターンを使用するため、そこで展開されます(ただし、そこに到達することはありません)。ただし、この関数は、find
の呼び出しのパターンに一致するものの最初のWordのみを使用します。
実際のショーストッパーは、パターンが[ -d $d ]
テストでも展開されることです。これは、-d
テストがsingleパス名。これが、結局、スクリプトが失敗する理由です。
代わりに、dir_array
に割り当てるときに、パターンが適切に展開されていることを確認してください。
dir_array=(
/srv/*/folderA
/srv/level1D/*/folderA
)
folderA
またはパス名の他の部分にスペースなどが含まれている場合、パス名のその部分は引用符で囲む必要がありますが、*
は引用符で囲まないでください。
また、引用符で囲む必要がないコンテキストがわかっている場合を除き、すべての変数の展開を二重引用符で囲むことを忘れないでください。
次の行に引用の問題がある可能性があります。
if [ -d $d ];then
find $1 -type f -mindepth 1 -maxdepth 1 -mtime +$FILEAGE -delete -print
dir_delete $d
また、変数データを出力するときは、printf
ではなくecho
を使用することを検討してください。
関連:
これは、*()を使用して変数内のワイルドカードを展開できる拡張globオプションを使用して行うことができます。
shopt -s extglob
dir_array=(
"/srv/*(*)/folderA"
"/srv/level1D/*(*)/folderA"
)
展開はd in ...で発生します。これが正しいポイントだと思います。