【问题标题】:"set -e" in shell and command substitutionshell 和命令替换中的“set -e”
【发布时间】:2010-12-30 02:40:24
【问题描述】:

在 shell 脚本中,set -e 通常用于在脚本执行的某些命令以非零退出代码退出时停止脚本,从而使它们更加健壮。

通常很容易通过在末尾添加|| true 来指定您不关心某些命令是否成功。

当您真正关心返回值,但不希望脚本在非零返回码上停止时,就会出现问题,例如:

output=$(possibly-failing-command)
if [ 0 == $? -a -n "$output" ]; then
  ...
else
  ...
fi

这里我们要检查退出代码(因此我们不能在命令替换表达式中使用|| true)并获取输出。但是,如果命令替换中的命令失败,整个脚本会因为set -e而停止。

是否有一种干净的方法可以防止脚本在此处停止而不取消设置 -e 并在之后将其设置回来?

【问题讨论】:

  • 取消设置-e有什么问题?

标签: shell robustness


【解决方案1】:

是的,在 if 语句中内联进程替换

#!/bin/bash

set -e

if ! output=$(possibly-failing-command); then
  ...
else
  ...
fi

命令失败

$ ( set -e; if ! output=$(ls -l blah); then echo "command failed"; else echo "output is -->$output<--"; fi )
/bin/ls: cannot access blah: No such file or directory
command failed

命令工作

$ ( set -e; if ! output=$(ls -l core); then echo "command failed"; else echo "output is: $output"; fi )
output is: -rw------- 1 siegex users 139264 2010-12-01 02:02 core

【讨论】:

  • 谢谢,这行得通!出于某种原因,虽然我收到了两次ls: blah: No such file or directory 消息。任何想法为什么?
  • 我只是举了你的例子ls -l blah,它显示了两次消息
  • @ivant 嗯,我真的不能说为什么会这样。出于好奇,第二个是否以output is: 为前缀?如果您将 blah 更改为像 as9dfasdf0afd 这样疯狂的东西,会发生这种情况吗?
  • 无所谓,是什么,只要文件不存在即可。我实际上找到了原因:它在zsh 下打印两次,在bash 下打印一次。
  • @ivant 这很有趣。不太确定是什么导致zsh 表现得那样。不过要注意
猜你喜欢
  • 2014-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 2018-08-06
  • 1970-01-01
相关资源
最近更新 更多