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

sun*_*sen 4 bash zsh sh

我正在处理备份脚本,并希望在出现错误时停止脚本,但某些命令除外,例如veracrypt --mount已安装时返回 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"
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 9

如果主命令失败,您可以使用它||来执行不会失败的内容,例如:

blah || true
{ yada; yada; yada; } || true
Run Code Online (Sandbox Code Playgroud)

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


另一种可能性是利用以下事实:如果它是 的一部分,则不会被视为失败if

if blah ; then true ; fi
Run Code Online (Sandbox Code Playgroud)

即使blah出错,脚本也会继续运行。


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

set +e ; blah ; set -e
Run Code Online (Sandbox Code Playgroud)

只有当您已经知道当前设置时,此解决方案才真正可行。你可能希望启用-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
Run Code Online (Sandbox Code Playgroud)

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