Reputation: 307
Shell scripting newb here. first thank you all in advance for any time and effort you put helping me with this issue.
I needed to create a shell script and a cron job to delete /tmp and sessions stored in a custom directory.
I've been learning the basics for few days now and am attempting my first shell script and cron job.
Am stumped at the best way to run multiple shell commands that allows commands to go thru even if others fail. I also want a log report and email sent for those commands that fail.
Am aware I can use either the ampersand(&&) or semi-colon. Am also aware the ampersand allows exit-error checking, while the semi-colon does not.
Here's my script
TmpPurge.sh
#!/bin/bash
find /home/username/sessions -iname 'sess_*' -mmin +480 -exec rm -rf {} \; &&
find /home/username/sessions -iname 'sess_*' -mmin +240 -exec rm -rf {} \; &&
/usr/sbin/tmpwatch -umc 5 /home/username/sessions &&
/usr/sbin/tmpwatch -umc 6 /var/tmp &&
/usr/sbin/tmpwatch -umc 12 /var/cache/eaccelerator
if [ $? = 0 ];
then
echo "$(date) Tmp purge completed successfully with error code: $?. " >> /home/username/logs/TmpPurge.log
else
echo "$(date) Tmp purge exited with error code: $?. " >> /home/username/logs/TmpPurge.log
fi
echo -e "\r" >> /home/username/logs/TmpPurge.log
Cron job:
20 3 * * * /bin/sh /home/username/scriptsdir/TmpPurge.sh > /home/username/logs/TmpPurge.log 2>&1
Question1: Is the script correct ? Question2: What is the best way to run above multiple commands? Would it be the above or
find /home/username/sessions -iname 'sess_*' -mmin +480 -exec rm -rf {} \;
find /home/username/sessions -iname 'sess_*' -mmin +240 -exec rm -rf {} \;
/usr/sbin/tmpwatch -umc 5 /home/username/sessions;
/usr/sbin/tmpwatch -umc 6 /var/tmp;
/usr/sbin/tmpwatch -umc 12 /var/cache/eaccelerator
or
/usr/sbin/tmpwatch -umc 5 /home/username/sessions\%
/usr/sbin/tmpwatch -umc 6 /var/tmp\%
/usr/sbin/tmpwatch -umc 12 /var/cache/eaccelerator\%
Upvotes: 0
Views: 476
Reputation: 5072
An alternative way to check for errors is through the "||" operator
command || exit 1 # Will exit with return code 1 if command fails
The idea is simple:
&& and || are used to chain commands together (unlike ";", which is used to separate commands).
&& is the AND operator, meaning that each successive commands will run only if the previous commands succeed (exit with 0).
|| is the OR operator, meaning that each successive commands will only run if the previous command fails (exit with a value different than 0).
; is used to end a command (or a command chain). If a line abruptly ends, the shell (at least most shells that I know) assumes the line ended with a ;. If you don't want this, you need to end the line with \, but the shell will join the lines together before running it as one single line.
Also note that you can chain these together:
echo a && echo b && ls /dir/doesnt/exist && echo c; echo d || echo e; ls /dir/doesnt/exist || echo f
Will print:
a
b
d
f
Also note that you can also mix various &&s and ||s in a left-associate manner:
echo a && ls /dir/doesnt/exist || echo b
prints:
a
b
Upvotes: 1
Reputation: 6426
The first way, with the commands chained together with &&
, will stop at the first error, and report that error. If you use semicolons ;
(which are actually unnecessary, if you put each command on a new line), then they'll all run, regardless if any of them failed, and your if [ $? -eq 0 ]
check will only notice and report an error if the last command has an error. So I don't think that's what you want.
Alternately, you could add if [ $? -ne 0 ]
checks after each command. Maybe try whatever looks the clearest and most understandable.
Also, cleaning out tmp with cron jobs and find
and -exec rm -rf {}
can be dangerous if it's a multiuser system, just google around to see what I mean. Someone's probably got some good, safe code you could look at.
Upvotes: 1