2

I want to copy all files with the extension .beta from one directory to another and then send an email with following format.

The following files have been moved from directory A to Directory B: 
1. la.beta
2. pa.beta

The email must be sent only if such files were found and were successfully moved.

This is what I have so far. The problem with this script is that it errors out if no files were found:

mv: cannot stat `/home/zaree/*.beta': No such file or directory`  

Also, I receive an email even though the file is not moved.

#!/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" zaree@xyz.com
glenn jackman
  • 85,964

2 Answers2

3

Add the following line before your for FILE in...:

shopt -s nullglob

This prevents that the loop is entered once if there are no files found. In your case the loop is entered with *.beta and the mv command is trying to move the *.beta into your target directory

Next thing is that your | mailx -s "Dev-Script" zaree@xyz.com part is best appended to the printf $BODY line so it is only executed when $FILE_FOUND equals to 1.

Lambert
  • 12,680
0

The first issue, dealing with cases where there are no files, can be done by using bash's nullglob feature. As explained in man bash:

nullglob

If set, bash allows patterns which match no files (see Pathname Expansion above) to expand to a null string, rather than themselves.

A better way though would be to not use a loop at all. Instead, use the && and || operators to control when the mail is sent. You could simplify your script to:

#!/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" zaree@xyz.com || 
    echo "No files found" >&2
terdon
  • 242,166