bash:错误处理和函数

标签 bash

我正在尝试在循环中调用一个函数,并在它抛出时优雅地处理并继续。

如果我省略 || handle_error 它只是像预期的那样停止整个脚本。

如果我离开|| handle_error 它会在错误后打印 foo is fine 并且根本不会执行 handle_error 。这也是预期的行为,它就是这样工作的。

#!/bin/bash

set -e

things=(foo bar)

function do_something {
  echo "param: $1"

  # just throw on first loop run
  # this statement is just a way to selectively throw
  # not part of a real use case scenario where the command(s)
  # may or may not throw
  if [[ $1 == "foo" ]]; then
    throw_error
  fi

  # this line should not be executed when $1 is "foo"
  echo "$1 is fine."
}

function handle_error {
  echo "$1 failed."
}

for thing in ${things[@]}; do
  do_something $thing || handle_error $thing
done

echo "done"

产量

param: foo
./test.sh: line 12: throw_error: command not found
foo is fine.
param: bar
bar is fine.
done

我想要的是

param: foo
./test.sh: line 12: throw_error: command not found
foo failed.
param: bar
bar is fine.
done

编辑:

do_something 实际上不需要返回任何东西。这只是一个抛出函数的示例,我可能会从示例源代码中删除它,因为我无法控制它的内容,我也不想控制它,并且测试其中的每个命令是否失败是不可行的。

编辑:

您不能触及do_something 逻辑。我之前说过,它只是一个包含一组可能会抛出错误的指令的函数。可能是笔误,可能是make在CI环境下失败,也可能是网络错误。

最佳答案

我找到的解决方案是将函数保存在单独的文件中并在子shell中执行。缺点是我们失去了所有本地人。

do-something.sh

#!/bin/bash

set -e

echo "param: $1"

if [[ $1 == "foo" ]]; then
  throw_error
fi

echo "$1 is fine."

我的脚本.sh

#!/bin/bash

set -e

things=(foo bar)

function handle_error {
  echo "$1 failed."
}

for thing in "${things[@]}"; do
  ./do-something.sh "$thing" || handle_error "$thing"
done

echo "done"

产量

param: foo
./do-something.sh: line 8: throw_error: command not found
foo failed.
param: bar
bar is fine.
done

如果有更优雅的方法,我会将其标记为正确答案。将在 48 小时内再次检查。

编辑

感谢@PeterCordes 的评论和 this other answer我找到了另一种不需要单独文件的解决方案。

#!/bin/bash

set -e

things=(foo bar)

function do_something {
  echo "param: $1"

  if [[ $1 == "foo" ]]; then
    throw_error
  fi

  echo "$1 is fine."
}

function handle_error {
  echo "$1 failed with code: $2"
}

for thing in "${things[@]}"; do
  set +e; (set -e; do_something "$thing"); error=$?; set -e
  ((error)) && handle_error "$thing" $error
done

echo "done"

正确产生

param:  foo
./test.sh: line 11: throw_error: command not found
foo failed with code: 127
param:  bar
bar is fine.
done

关于bash:错误处理和函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33704036/

相关文章:

linux - bash shell 中的管道是如何实现的?

mysql - 转义变量mysql密码

linux - 使用 shell 脚本填充 Excel 工作表列中的值

bash - 将 bash 数组转换为 awk 数组

linux - BASH If [[ "$a"== *"$b"* ]] 始终为真,即使它不应该为真

linux - 如何使用 bash 垂直组织变量中的单词?

arrays - 如何将一个值添加到数组的中间?

linux - 在 bash 脚本中选择命令行或菜单

linux - 遍历 linux 中标题中不同数字的文件

python - 从日期时间转换为 GPS 时间