1

I am trying to attach multiple files in Unix, which are the result of a find command. When I try to send the mail, the attachments are missing.

dir=$path
echo "Entered into $spr/sum_master"
for fil in `find $dir -ctime -2 -type f -name "Sum*pdf*"`
do
  uFiles=`echo "$uFiles ; uuencode $fil  $fil"`
done
\($uFiles\) | mailx -s "subject" abc@gmail.com

What is wrong with this code?

Aravind
  • 1,599

1 Answers1

0

If uFiles ends up containing the string foo bar qux, then the last line runs the command (foo with the arguments bar and qux). This results in the error message (foo: command not found (or similar), and mail gets an empty input.

That's not the only problem with the script. The command that builds up the uFiles variable doesn't do at all what you think it does. Run bash -x /path/to/script to see a trace of the script, it'll give you an idea of what's happening. You're echoing the uuencode command instead of running it. You don't need echo there:

  uFiles="$uFiles
  $(uuencode "$fil" "$fil")"

That will make the loop work, but it's brittle; in particular, it will break on file names containing spaces and other special characters (see Why does my shell script choke on whitespace or other special characters? for more explanations). Parsing the output of find is rarely the easiest way to do something. Instead, tell find to execute the command you want to execute.

find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \;

The output of that is the concatenation of the uuencoded files that you were trying to build. You can pass it as input to mail directly:

find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \; |
mailx -s "subject" abc@gmail.com

If you want to detect potential failures of the uuencode step, you can stuff it into a variable (but beware that it might be very big):

attachments=$(find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \;)
if [ $? -ne 0 ]; then
  echo 1>&2 "Error while encoding attachments, aborting."
  exit 2
fi
if [ -z "$attachments" ]; then
  echo 1>&2 "Notice: no files to attach, so mail not sent."
  exit 0
fi
echo "$attachments" | mailx -s "subject" abc@gmail.com

Alternatively, write a temporary file.

attachments=
trap 'rm -f "$attachments"' EXIT HUP INT TERM
attachments=$(mktemp)
find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \; >"$attachments"
if [ $? -ne 0 ]; then
  echo 1>&2 "Error while encoding attachments, aborting."
  exit 2
fi
if ! [ -s "$attachments" ]; then
  echo 1>&2 "Notice: no files to attach, so mail not sent."
  exit 0
fi
mailx -s "subject" abc@gmail.com <"$attachments"