配列に格納されている複数のディレクトリをクリアしようとしています。これは簡単な例です(私はより多くのディレクトリを持っています)。
#!/bin/bash
$IMAGES_DIR="/Users/michael/scripts/imagefiles"
$BACKUP_DIR="/Users/michael/scripts/imagebackups"
...
array=( $IMAGES_DIR $BACKUP_DIR )
for i in ${array[@]}
do
if [ "$(ls -A $i)" ]; then # check that directory has files in it
rm "$i/"* # remove them
fi
done
ディレクトリごとにエラーが発生します。例:
rm:/ Users/michael/scripts/imagefiles/*:そのようなファイルやディレクトリはありません
単一のコマンドですべてを達成するのはどうですか?
1つのfind
呼び出しで、ファイルの存在チェック、グロビング、および削除をキャプチャできます。 GNUバージョンのfind
の場合、次のようになります。
for f in "${array[@]}"; do
find "$f" -type f -delete
done
GNU find
がない場合は、次の呼び出しを使用します。
find "$f" -type f -exec rm -f {} +
(ディレクトリ階層全体からファイルをクリアするのではなく、直接の子であるファイルのみをクリアする場合は、-maxdepth 1
の前に-type f
を追加します。)
待ってください、まだまだあります...
John1024 wisely notes 配列を最初のパラメータとしてfind
に渡すことにより、ループを完全に無視できます。
find "${array[@]}" -type f -delete
これは、1)find
が、1回の実行で検索および処理される複数のディレクトリを受け入れるためです2)シェルは、各要素(ディレクトリ)がfind
への個別の位置パラメーターになるように配列を分割します。
コードを次のように変更します。
_#!/bin/bash
IMAGES_DIR="/Users/michael/scripts/imagefiles"
BACKUP_DIR="/Users/michael/scripts/imagebackups"
array=( $IMAGES_DIR $BACKUP_DIR )
for i in "${array[@]}"
do
if [ "$(ls -A "$i")" ]; then
rm "${i:?}"/*
fi
done
_
エラー:
$
_を配置するif [ "$(ls -A $i)" ];then
で_$i
_を引用しない"${var:?}"
_を使用します。_rm "$i/"*
_は_/*
_に展開されませんチェックするために外部プロセスを呼び出さないでください、しかしシェルの内部関数testを使用してください
if test -d "$ i";次に#ディレクトリが存在することを確認します
テストとrmの呼び出しの間に、他のプロセスがすでにディレクトリを消去した可能性があるため、rmは失敗します。スイッチを使用できます-fまたはエラーをリダイレクトします
/ bin/rm "$ i/*" 2>/dev/null#ファイルを削除します
rm
の-f
オプションを使用すると、ファイルオペランドが存在しない場合でもユーティリティはメッセージを表示しません。また、失敗しても終了しません。
おそらくとは、あなたの場合、1つまたは複数のディレクトリが非表示の名前のファイルまたはディレクトリを除いて空であるため、パターンの最後の*
が何でも。 bash
シェルオプションを設定することにより、*
グロブをdotglob
の非表示の名前に一致させることができます。
また、割り当ての変数名に$
を付けないでください。Wordの分割とファイル名の生成(グロビング)を回避するために、変数展開を二重引用符で囲む必要があります。変数名は小文字にする必要があります。これにより、環境変数や特別なシェル変数を誤って上書きすることがなくなります。
これらを考慮したコードの代替の定式化。
#!/bin/bash
shopt -s dotglob
images_dir="/Users/michael/scripts/imagefiles"
backup_dir="/Users/michael/scripts/imagebackups"
dirs=( "$images_dir" "$backup_dir" )
for dir in "${dirs[@]}"; do
rm -f "$dir"/*
done
上記はディレクトリからすべてのファイルを削除しようとします。ディレクトリにサブディレクトリがある場合、これに関してrm
からエラーが発生します。これらも削除したい場合は、rm
とともに-r
を使用してください。