Reputation: 833
I was trying to make a small script to check if backup drive is fine and its disk usage details, and to add it to nagios as an active check in servers. Once I written one, I got some unknown errors that I don't to correct.
Script is:
#!/bin/sh
BACKUP_DRIVE='/backup'
if [[ "$( grep $BACKUP_DRIVE /etc/fstab | awk '{print $2}')" -ne "0" ]]; then
if [[ "$( df -h | grep $BACKUP_DRIVE | awk '{print $6}')" -ne "0" ]]; then
if [[ "$( df -h|grep backup|awk '{print $5}' | cut -d "%" -f1)" -ge "95" ]]; then
echo "CRITICAL: Backup Drive usage exceeded 95%"
fi
else
echo "CRITICAL: Backup Drive not mounted"
fi
else
echo "CRITICAL: Backup Drive not added in fstab"
fi
Error is:
# sh /usr/local/src/backupcheck.sh
/usr/local/src/backupcheck.sh: line 6: [[: /backup: syntax error: operand expected (error token is "/backup")
CRITICAL: Backup Drive not added in fstab
It's getting error at the first if condition itself and not getting into the inner if conditions.
Is there any corrections need to be done at point where variable $BACKUP_DRIVE mentioned? Please help as I am a beginner to bash scripting.
Upvotes: 2
Views: 5932
Reputation: 440689
The immediate issue - likely the one triggering the syntax error - is:
You're using shebang #!/bin/sh
, which is NOT guaranteed to be bash
(and even if it is, it behaves differently), yet you're using bash-specific syntax ([[ ... ]]
).
#!/bin/bash
as the shebang instead.bash
, not sh
; in your example: bash /usr/local/src/backupcheck.sh
Alternatively, with the shebang as is and if you want to be able to invoke your script explicitly with sh
:
[[ ... ]]
with [ ... ]
(but in the general case typically requires more changes). You can only get away without rewriting if you know for sure that sh
is actually bash
on your system and you do not need the script to be portable (run on other platforms).
However, there are also issues with your conditionals:
It looks like your first 2 conditionals are meant to only test whether the enclosed command succeeds or not.
Generally, you do not need [[ ... ]]
for such tests at all, and instead simply use the command directly with if
, possibly negated with !
, and with output suppressed as needed with >/dev/null
or 2>/dev/null
:
Thus, instead of your command:
if [[ "$( grep $BACKUP_DRIVE /etc/fstab | awk '{print $2}')" -ne "0" ]]; then
you should use:
if grep $BACKUP_DRIVE /etc/fstab >/dev/null; then
grep
will indicate having found (at least) a match with exit code 0
, which is (also) success from if
's perspective. Thus, effectively, the if
command's body will be executed if the backup drive exists.
Note that I've removed the awk
command, as it (a) isn't necessary for the test and (b) actually defeats the test in that it will cause the overall result to be 0
(success), even if the grep
command failed.
Similarly, your 2nd conditional should read:
if df -h | grep $BACKUP_DRIVE >/dev/null; then
Finally, your 3rd conditional is correct in principle: it captures stdout output from the pipeline and compares it to a percentage number (though double-quoting the number is not necessary and potentially confusing). However, you accidentally hard-coded the drive name, so instead it should be:
if [[ "$(df -h | grep $BACKUP_DRIVE | awk '{print $5}' | cut -d "%" -f1)" -ge 95 ]]; then
Finally:
stderr
by redirecting the echo
commands with 2>/dev/null
; similarly, you should use exit 1
(or any other nonzero exit code) to exit in case of error, so as to properly signal an error condition.Upvotes: 6
Reputation: 5459
At some point, it's trying to evaluate the $BACKUP_DRIVE
parameter as a math expression. Try this instead:
grep $BACKUP_DRIVE /etc/fstab | awk '{print $2}'
if [[ $? -ne 0 ]] ; then
...
Upvotes: 1