Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use "set -e" but allow certain commands to fail?

Tags:

bash

sh

zsh

I am working on a backup script and would like to stop the script on error except for certain commands such as veracrypt --mount which returns 1 when already mounted.

#! /bin/sh

set -e

veracrypt --text --mount --pim 0 --keyfiles "" --protect-hidden no "/Volumes/Samsung BAR/.b" /Volumes/Backup

borg check /Volumes/Backup/Borg

veracrypt --text --dismount "$BACKUP_VOLUME_PATH"
like image 821
sunknudsen Avatar asked Dec 31 '22 21:12

sunknudsen


1 Answers

You can use || to execute something that won't fail if a primary command fails, such as with:

blah || true
{ yada; yada; yada; } || true

Without the || true, the script will complain on error then stop. With it, you'll still see the error but the script will carry on.


Another possibility is taking advantage of the fact that it's not considered a failure if it's part of an if:

if blah ; then true ; fi

Even if blah errors, the script will carry on.


Finally, you can turn it off temporarily for a specific command:

set +e ; blah ; set -e

This solution is only really workable if you already know the current setting. You probably don't want to turn on -e unless it was set before you turned it off.

To detect its current setting and only turn it back on if it was already on beforehand, you can use:

# 1: State here can be either +e or -e. If -e, record that fact and make +e.

eWasSet=false; [[ $- = *e* ]] && eWasSet=true && set +e

# 2: Do stuff that needs +e.

blah blah blah

# 3: Revert state if needed. After this, it's as it was in comment 1 above.

${eWasSet} && set -e

This works because $- contains all of the current set values (like ehB for error exit, hashing, and brace expansion), so you can use the wildcard equality operators to find out if a particular setting (like e) is active.

like image 66
paxdiablo Avatar answered Jan 02 '23 12:01

paxdiablo