19

I'm writing a bash script and I have errexit set, so that the script will die if any command doesn't return a 0 exit code, i.e. if any command doesn't complete successfully. This is to make sure that my bash script is robust.

I have to mount some filesystems, copy some files over, the umount it. I'm putting a umount /mnt/temp at the start so that it'll umount it before doing anything. However if it's not mounted then umount will fail and stop my script.

Is it possible to do a umount --dont-fail-if-not-mounted /mnt/temp? So that it will return 0 if the device isn't mounted? Like rm -f?

Rory
  • 48,706
  • 67
  • 174
  • 234

4 Answers4

41

The standard trick to ignore the return code is to wrap the command in a boolean expression that always evaluates to success:

umount .... || /bin/true
Andy Ross
  • 10,859
  • 1
  • 28
  • 29
  • 3
    and redirect output to /dev/null: umount … > /dev/null 2>&1 || /bin/true – knittl Sep 04 '09 at 10:22
  • Well, that's sorta situational. It's easy to imagine a script wanting to continue, but leave any error messages in the log stream. – Andy Ross Sep 04 '09 at 10:44
  • 9
    You can make this a little faster by using the pseudo-command `:` (a shell builtin) instead of /bin/true (which creates a new process). That is, use "`umount .... || :`" – Gordon Davisson Sep 05 '09 at 08:34
  • 7
    This assumes that the error reported by umount is because it was not mounted in the first place, but what about the case where the umount fails for other reasons? This could be dangerous! – Lennart Rolland May 29 '15 at 18:34
  • 6
    This is **DANGEROUS** -- like @LennartRolland said, you have no idea why umount failed here. The device may actually be busy and the umount may have failed Please don't use this!! – user541686 May 20 '18 at 22:45
7

Assuming that your umount returns 1 when device isn't mounted, you can do it like that:

umount … || [ $? -eq 1 ]

Then bash will assume no error if umount returns 0 or 1 (i.e. unmounts successfully or device isn't mounted) but will stop the script if any other code is returned (e.g. you have no permissions to unmount the device).

Michał Górny
  • 16,912
  • 2
  • 46
  • 75
  • 3
    I tested and umount quits with return 1 both for busy and not mounted so it is not possible to distinguish the two cases based on return code alone. – Lennart Rolland May 29 '15 at 18:41
  • Actually the return code is the number of mount points that failed to unmount, at least for util-linux's `umount`. Cf. https://github.com/karelzak/util-linux/blob/master/sys-utils/umount.c – stefanct Feb 15 '19 at 12:44
4

I just found the ":" more use ful and wanted a similar solution but let the script know whats happening.

umount ...... || { echo "umount failed but not to worry" ; : ; } 

This returns true with the message, though the umount failed.

alony
  • 10,325
  • 3
  • 34
  • 46
benki
  • 41
  • 1
  • Most of the times it's more useful to use "/bin/true" for this purpose, it's then easier to read and see what it means. – anydot Oct 20 '12 at 13:48
  • 1
    Aren't the `{}` and `; : ;` redundant here? I tested `if false || echo 1 ; then echo ok ; fi` and the output was the same as `if false || { echo 1 ; : ; } ; then echo ok ; fi`. – Desty Oct 15 '14 at 14:37
2

Ignoring exit codes isn't really safe as it won't distinguish between something that is already unmounted and a failure to unmount a mounted resource.

I'd recommend testing that the path is mounted with mountpoint which returns 0 if and only if the given path is a mounted resource.

This script will exit with 0 if the given path was not mounted otherwise it give the exit code from umount.

#!/bin/sh

if mountpoint -q "$1"; then
  umount "$1"
fi

You an also do it as a one liner.

! mountpoint -q "$mymount" || umount "$mymount"
Dev
  • 10,959
  • 3
  • 36
  • 50