I'm not going to bother to look deeply at the operational flow right now, but I will go line-by-line and offer advice on the common issues I spot in the code itself.
1)
Code:
EMAIL=<my_email>
HOST=`hostname`
Since environment variables are generally all upper-case, it's good practice to keep your own user variables in lower-case or mixed-case to help differentiate them.
$(..) is highly recommended over `..`
2)
Code:
TMPFILE=$BASEDIR/tmp_mailen.tmp
Make sure you double-quote all variable and command substitutions, unless you want them to be subsequently word-split and filename expanded. (This isn't the best example line, but this was the first place it popped up, and it's so important it needs to be mentioned right away.)
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes
3)
Code:
flags[a]=$1
let a=a+1
let is unnecessary here. The index fields of regular arrays operate in an arithmetic environment, so you can increment the counter variable directly.
You can also use the "
+=()" pattern to append directly to an array, without having to deal with a counter.
Code:
flags[a++]=$1
#or
flags+=( "$1" )
4)
Code:
BASEFILE=`basename $1`
uuencode $1 $BASEFILE >> $TMPFILE
See #1 and 2 above.
But also, basename is superfluous.
parameter substitution can do the job.
Code:
basefile=${1##*/}
uuencode "$1" "$basefile" >> "$tmpfile"
5)
Code:
if [[ ${I_ARGS} == 0 ]]
then
PRINT_USE
exit 1
fi
The full bracketed form of the variable just adds unnecessary clutter here. I recommend leaving them off.
When doing integer comparisons, it's better to use
((..)) arithmetic evaluation brackets.
Error messages should generally be output to stderr instead of stdout.
Many scripters feel that it's more readable to place the "
do/then" keywords on the same line as the "
for/while/until/if" keywords, as it more clearly separates the outside block from the inside block.
Code:
if (( i_args == 0 )); then
print_use >&2
exit 1
fi
6)
Code:
echo "Temporary file already exists, overwrite? (y/n)"
read DELETE
if [[ ${DELETE} == 'y' ]]
then
rm ${TMPFILE}
else
echo "Could not use temporary file: ${TMPFILE}"
exit 1
fi
To be more robust, you should test for multiple input variations. A
case statement is often more useful for doing that. Also, you can embed the whole thing in a loop to force re-reads on improper input.
Code:
while true; do
read -p "Temporary file already exists, overwrite? (y/n): " reply
case $reply in
[yY]*) rm "$tmpfile"
echo "Previous Temporary file removed."
break ;;
[nN]*) echo "Could not use temporary file: $tmpfile"
exit 1 ;;
*) echo "Unknown option. Please enter yes or no." ;;
esac
done >&2
7)
Code:
# Loop through all arguments given
Consider using
getopts for parsing options, instead of doing all the work yourself.
http://wiki.bash-hackers.org/howto/getopts_tutorial
8)
Code:
for FILE in ${files[*]}
The "
*" index outputs the entire array as a single string, which since you didn't quote it, is then subsequently re-word-split. If any of the array values contain spaces, they will not be read properly.
Instead, use the "
@" index, which outputs the array as individual strings, and when quoted, acts as if each entry is quoted separately.
Code:
for file in "${files[@]}"; do
9)
Code:
if [[ ! -e ${FILE} ]]
then
if [[ ! -e `pwd`/${FILE} ]]
Instead of using "
-e" (file exists), use "
-r" (file exists and is readable).
Don't use the
pwd command, use the built-in
$PWD environment variable (there's also
$HOME,
$USER, and a few others. See the bash manpage for a full list).
10)
Code:
echo "Mail sent from UNIX" | mail -s "Files sent from ${HOST}" ${EMAIL} < $TMPFILE
This doesn't look right to me. You have
mail receiving input from both a pipe and a file redirection. I don't think it can work that way.
And again, quote your variables.
11)
Code:
# Cleanup after sending e-mail
rm $TMPFILE
No problem here, really. But it would be wise to set up a
trap instead to handle the cleanup. That way it won't leave tempfiles around if the script aborts suddenly for some reason or is ctrl+c cancelled.
(Sorry no link offhand. Search the web.)
See these links for more general advice on common scripting errors:
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
http://wiki.bash-hackers.org/scripting/newbie_traps
Overall, I think you've made a good start at shell scripting. Keep up the good work!