我想将具有扩展名的所有文件.beta
从一个目录复制到另一个目录,然后发送以下格式的电子邮件。
The following files have been moved from directory A to Directory B:
1. la.beta
2. pa.beta
仅当找到此类文件并成功移动时才必须发送电子邮件。
这是我到目前为止所拥有的。该脚本的问题是,如果未找到文件,则会出错:
mv: cannot stat `/home/zaree/*.beta': No such file or directory`
此外,即使文件未移动,我也会收到一封电子邮件。
#!/usr/bin/env bash
FROM_DIR='/home/zaree'
TO_DIR='/home/zaree/test'
FILE_FOUND=0
BODY=$(printf "$(date)\n\n")
BODY+=$(printf "The following files have been moved from\n")
BODY+=$(printf "%s\nto\n%s\n\n" "$FROM_DIR" "$TO_DIR")
for FILE in /home/zaree/*.beta; do
FILE_FOUND=1
mv $FILE /home/zaree/test
BODY+=$(printf "%s moved\n" "$FILE");
done
{
if (( $FILE_FOUND==1 )); then
printf "$BODY"
fi
} | mailx -s "Dev-Script" [email protected]
答案1
在您的之前添加以下行for FILE in...
:
shopt -s nullglob
这可以防止在没有找到文件的情况下进入循环一次。在您的情况下,进入循环*.beta
并且mv
命令尝试将其移动*.beta
到您的目标目录中
接下来的事情是你的部分最好附加到该行,因此它仅在等于 1 时执行。| mailx -s "Dev-Script" [email protected]
printf $BODY
$FILE_FOUND
答案2
第一个问题,处理没有文件的情况,可以通过使用 bash 的nullglob
功能来完成。正如中所解释的man bash
:
空球
如果设置,bash 允许不匹配任何文件的模式(请参阅上面的路径名扩展)扩展为空字符串,而不是它们本身。
更好的方法是根本不使用循环。相反,使用&&
和||
运算符控制何时发送邮件。您可以将脚本简化为:
#!/usr/bin/env bash
FROM_DIR='/home/zaree'
TO_DIR='/home/zaree/test'
## Prepare the message. You can collect all the names
## here directly. The cat -n adds line numbers.
BODY=$(cat<<EOF
$(date)
The following files have been moved from
$FROM_DIR to $TO_DIR:
$(printf "%s\n" "$FROM_DIR"/*.beta | cat -n)
EOF
)
mv "$FROM_DIR"/*.beta "$TO_DIR" 2>/dev/null &&
printf "%s\n" "$BODY" | mailx -s "Dev-Script" [email protected] ||
echo "No files found" >&2