对 shell 脚本相当陌生,想要编写脚本来检查服务器 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/错误.txt要记录所有错误,两个文件都用于保持日志均匀网络故障:
笔记:
- 你不应该解析的输出
ls
- mailx -E 以避免空正文,因此如果没有移动文件,则不会发送
- mailx只有一个如果
mv
遇到错误,通过使用break
提前中断而不是exit 1
因为我们仍然想知道在错误发生之前哪个文件已被移动。 cmd; if [ $? -eq 0 ]
隐式比较的优点if cmd
是您可以轻松地将其修改为可能需要不同返回代码的其他命令。- 您应该手动删除 /tmp/error.txt 和 /tmp/moved.log ,它们会不时附加。
参考:
答案2
像这样的事情应该可以解决问题。如果您需要远程访问服务器,请使用 ssh 证书并使用 ssh 执行此脚本。
#! /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
答案3
只是为了好玩
#! /bin/bash
ls /exports/files/*.300 | while read FILE
do
if mv $FILE /exports/files/arch
then echo "$FILE moved"
fi
done | mailx -s files moved [email protected]
将为您提供一封包含所有移动文件的邮件,并跳过错误。
只有 3 层管道。
编辑:
文件很少:
#! /bin/bash
if ls /exports/files/*.300 > /dev/null 2>&1
then
ls /exports/files/*.300 | awk '{printf "%s moved\n",$0 }' | mailx -s files moved [email protected]
mv /exports/files/*.300 /exports/files/arch
else
echo no .300 file found | mailx -s no .300 files moved [email protected]
fi
如果 arg 列表太长
#! /bin/bash
if ls /exports/files/*.300 > /dev/null 2>&1
then
ls /exports/files/*.300 | while read FILE
do
if mv $FILE /exports/files/arch
then echo "$FILE moved"
fi
done | mailx -s files moved [email protected]
fi