シェルスクリプトに初めてアクセスし、サーバー10.xx.xx.xx.300
にファイル拡張子があることを確認するスクリプトを作成しようとしています。ファイルが存在する/exports/files
場合は、*.300
ファイルをに移動し/exports/files/arch
て電子メールを送信してください[email protected]
。見つからないと、*.300
何もしません。
私は次の提案を試しました。
#! /bin/bash
for FILE in `ls /exports/files/*.300`
do
mv $FILE /exports/files/arch
echo "$FILE moved" | mailx -s $FILE moved [email protected]
done
ファイルが存在しないとエラーが発生して表示されますls: cannot access /exports/files/*.300: No such file or directory
。これを抑制する方法はありますか?
ベストアンサー1
【書き直す】
#!/usr/bin/env bash
shopt -s nullglob #to make `("$src_dir"*.300)` works
src_dir="/exports/files/" #don't forget trailing slash /
dest_dir="/exports/files/arch/" #don't forget trailing slash /
err_f="/tmp/error.txt"
mv_f="/tmp/moved.log" #record moved file in case network down
email="[email protected]"
touch "$err_f" #bcoz we use >> apppend
touch "$mv_f" #bcoz we use tee -a append
if [ ! -d "$src_dir" ]; then echo|mailx -s "Error: directory $src_dir not exist" "$email" 2>>"$err_f"; exit 1; fi
if [ ! -d "$dest_dir" ]; then echo|mailx -s "Error: directory $dest_dir not exist" "$email" 2>>"$err_f"; exit 1; fi
{
f=("$src_dir"*.300)
for ((i=0; i < ${#f[@]}; i+=1)); do
mv -f "${f[i]}" "$dest_dir" 2>>"$err_f"; #-f do not prompt
if [ $? -eq 0 ]; then
if [ "$i" -eq 0 ]; then echo "$(date +"%Y-%m-%d %H:%M:%S")"; echo "The following files has been moved from $src_dir to $dest_dir"; echo; fi
echo "$((i+1))." "$(basename "${f[i]}")" 'moved'; echo;
else
echo| mailx -s "Error: $(<"$err_f")" "$email" 2>>"$err_f"; break
fi
done
} | tee -a "$mv_f" | mailx -E -s "The following files has been moved" "$email" 2>>"$err_f"
電子メール受信トレイのスクリーンショットの例:
メールを受信中にエラーが発生しましたmv
。
成功後のメールの受信mv
:
/tmp/moved.logログファイルが移動し、/tmp/error.txtすべてのエラーを記録するには、両方のファイルを使用してログを均一に保ちます。ネットワーク障害:
メモ:
- 出力を解析しないでください。
ls
- mailx -E 空の本文を防止し、ファイルが移動されない場合は送信されません。
mv
mailxは、エラーが発生した場合にエラーが発生する前にどのファイルが移動されたかを知りたいので、break
代わりに早期中断を使用して1つしかありません。exit 1
cmd; if [ $? -eq 0 ]
暗黙的な比較の利点は、if cmd
他の戻りコードが必要な他のコマンドに対して簡単に変更できることです。- 随時添付されている/tmp/error.txt、/tmp/moved.logを手動で削除する必要があります。
引用: