Is there a way to perform an if statement based on the error output of a command?
For example, I want to use udisksctl
in a script which mounts a USB drive and then perform some action on the drive contents.
- The drive is not mounted: it should mount it and then perform the action.
- The drive is absent: it should throw an error message and exit;
- The drive is already mounted, it should perform the action;
Running udisksctl
can have three results in this scenario:
In case 1), it runs successfully.
In the other two cases it returns an error, but:
- In case 2), it gives me the error:
Error looking up object for device ...
- In case 3) it gives me the error:
Error mounting /dev/sdb1: GDBus.Error:org.freedesktop.UDisks2.Error.AlreadyMounted: Device /dev/sdb1 is already mounted at
Is there an elegant way to make an if statement which takes different actions based on these two error messages?
Piping the error message to grep like this udisksctl mount -b /dev/disk/by-label/CRUZER 2> >(grep -i "Error looking up object for device")
seems to make no difference in the output.
CodePudding user response:
Branching on the text of error messages is brittle; the text could change between versions, or you could get messages which are similar but mean different things, or the output could change to a different language depending on the user's locale. But to do what you are asking, try
if result=$(udiskctl mount -b /dev/disk/by-label/CRUZER 2>&1); then
: success
else
rc=$?
case $result in
*"Error looking up object for device"*)
echo case 2;;
*"Error mounting /dev/sdb"*)
echo case 3;;
*) echo "$0: unexpected error $result" >&2
exit $rc
;;
esac
fi
The case
inside the if
is a bit unattractive; I suppose you could refactor this to use elif
but then you'd have to refactor the capturing of the exit code from the failed command (assuming you care what the exit code was).
You could obviously make the search strings more or less specific; I tried to keep them fairly general.
CodePudding user response:
Thanks to @markp-fuso, this is what I got:
udtmp=$(mktemp /tmp/$(basename "$0".XXXXXXXX))
udisksctl mount -b /dev/disk/by-label/CRUZER 2> $udtmp
if grep -i "Error looking up object for device" $udtmp ; then
exit
elif grep -i "GDBus.Error:org.freedesktop.UDisks2.Error.AlreadyMounted" $udtmp ; then
do something
fi
do something else
@LMC thank you for the heads up. I think I'll be using it anyway because udiskctl
works well with Thunar and mnt
much less.