This is a script that must send an email at each new article published on a specific website. Any suggestions or improvements to do?
SENDER_EMAIL="[email protected]"
TO_EMAIL="[email protected]"
RSS_SITE="example.com/feed.xml"
CHECK_INTERVAL=10
while [ 1 ]; do
LINK_ARTICLE=$(rsstail -i 1 -u $RSS_SITE -l -n 0 -1 | grep -oP "Link:+ \K.*")
TITLE_ARTICLE=$(rsstail -i 1 -u $RSS_SITE -n 0 -1 | grep -oP "Title:+ \K.*")
if [ "$LINK_ARTICLE" != "" ] && [ "$TITLE_ARTICLE" != "" ]; then
echo "New article published on the site. TITLE: $TITLE_ARTICLE - LINK: $LINK_ARTICLE" | EMAIL="$SENDER_EMAIL" mutt -s "Nuovo Articolo BDO" "$TO_EMAIL"
echo "New article published on the site. TITLE: $TITLE_ARTICLE - LINK: $LINK_ARTICLE"
fi
sleep $CHECK_INTERVAL
done
1 Answer 1
I see a number of things that may help you improve your code.
Use "shebang" line
The shebang is the line at the beginning of a shell script that tells which program to use. In this case, you probably want this:
#! /usr/bin/env bash
See this question for details.
Consider using cron
instead of sleep
If this is something you want to run automatically, consider running it as a cron tab instead of using sleep
within the script.
Include some comments
The program requires rsstail
, mutt
and sleep
which is a requirement that should be documented in a comment.
Be cautious about handing variables to programs
The mutt
program, like many Linux programs, has a --
option which specifies that no further options are on the command line. This prevents the contents of $TO_EMAIL
in a line like the following from being misinterpreted as a command line option.
mutt -s $TITLE -- $TO_EMAIL < $BODYTEXT
Combine strings
The echo
is used twice with an identical string. An alternative approach is
TITLE="Nuovo Articolo BDO"
BODYTEXT="New article published on the site. TITLE: $TITLE_ARTICLE - LINK: $LINK_ARTICLE"
mutt -s $TITLE -- $TO_EMAIL < $BODYTEXT
echo $BODYTEXT
Avoid creating extraneous variables
Instead of creating SENDER_EMAIL
, you could just specify EMAIL
and then the reassignment of the latter variable before mutt
is called would not be necessary.
Consider writing a portable script
By sticking closely with Posix and avoiding bashisms your code could run on many different kinds of systems, including recent versions of Ubuntu which don't use bash
.
-
\$\begingroup\$ Hi, thanks for your meticulously written answer. Can you please explain why you would consider cron job instead of sleep in this case? Thanks. \$\endgroup\$Alex Jones– Alex Jones2020年12月05日 13:36:06 +00:00Commented Dec 5, 2020 at 13:36
-
\$\begingroup\$ One of the principles used in Linux is that programs are designed to do just one thing well. Because
cron
is a standard Linux tool to automatically run software on a periodic basis, I would probably use it for this application rather than having an infinitely running script. \$\endgroup\$Edward– Edward2020年12月05日 15:33:07 +00:00Commented Dec 5, 2020 at 15:33 -
\$\begingroup\$ I don't know about that. I think cron is just a bloat when I can do the same thing with while loop and sleep - using the same principle - use while loop to repeat stuff - use sleep to pause b/w execution. \$\endgroup\$Alex Jones– Alex Jones2020年12月10日 17:42:42 +00:00Commented Dec 10, 2020 at 17:42
-
\$\begingroup\$ The odds are about 99.9% that your system is already running
cron
so I don't think it reasonably qualifies as bloat. In any case, the advice was merely to consider its use. \$\endgroup\$Edward– Edward2020年12月10日 17:49:52 +00:00Commented Dec 10, 2020 at 17:49