是否可以使用 "set -e" 但允许某些命令失败?

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

我正在处理备份脚本,并希望在出现错误时停止脚本,但某些命令除外,例如 veracrypt --mount 其中 returns 1 已安装。

#! /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"

您可以使用 || 来执行一些 不会 在主要命令失败时失败的操作,例如:

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

如果没有 || true,脚本会报错然后停止。有了它,您仍然会看到错误,但脚本会继续。


另一种可能性是利用这样一个事实,即如果它是 if:

的一部分则不会被视为失败
if blah ; then true ; fi

即使 blah 错误,脚本也会继续。


最后,您可以针对特定命令暂时关闭它:

set +e ; blah ; set -e

只有当您已经知道当前设置时,此解决方案才真正可行。您可能不想打开-e,除非它是在您关闭之前设置的。

检测它的当前设置并且只在它之前已经打开时才重新打开它,您可以使用:

# 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

这是有效的,因为 $- 包含所有当前 set 值(如 ehB 用于错误退出、散列和大括号扩展),因此您可以使用通配符相等运算符查看特定设置(如 e)是否处于活动状态。