我正在创建一个 sh 文件以在后台运行多个命令。
在该文件的某行,有一个用于更新 zip 文件的命令,例如:
zip -d archive.zip file.txt
此 file.txt 可能并不总是 archive.zip 的一部分。如果不是,shell 脚本会在该行中中断:
zip warning: name not matched
我希望它继续到以下几行,忽略该文件的不存在。我怎样才能做到这一点?
答案1
通常在 shell 脚本中,即使是生成错误的行也不会阻止 shell 脚本的执行。它只会继续到下一行。
值得注意的例外是,如果您设置了标志,以便在任何子命令失败时退出 shell。有时可以通过在脚本顶部附近添加“set -e”来完成。如果您的脚本中有类似的内容,它将在脚本中的任何命令返回错误时中止。在这种情况下,您的选择是:
删除该选项。这可能会对脚本的其余部分产生影响,因此不要一时兴起这样做。
关闭您所在脚本部分的选项,然后重新打开以继续:
set +e zip -d archive.zip file.txt set -e
为失败的行提供一条出路,以便 shell 即使出现故障也将命令视为成功。可以通过多种方式完成此操作,但一种简单的方法是使用 OR 运算符:
zip -d archive.zip file.txt || true
这将运行 zip 命令,但如果失败,它将运行 true 命令,父 shell 将从中获取返回代码(当然,这是成功的)。你可能会看到有时这样写,
||:
它稍微快一些,更棘手,但并不神奇;:
只是碰巧是一个 shell 内置无操作命令,即使它什么也不做,也会返回成功错误代码。另一种方法是在子 shell 中运行该命令,将其包围起来,
()
这样虽然其中的命令可能会失败,但子 shell 会完成其工作,因此带有set -e
set 的父脚本不会终止。对于单个命令来说,这不是最佳选择,但如果您想运行一整套命令,这可能会很有用。
另一方面,如果您只想抑制 zip 生成的错误消息,则可以使用 ( 2> /dev/null
) 将标准错误流重定向到 /dev/null 以抑制生成的消息(或使用 关闭它2>&-
)。