bash - 使用$(func)调用有问题的函数时,Bash脚本不会在第一次 “exit”调用时退出

标签 bash function error-handling

抱歉,我无法给出明确的标题,但这里是简化的问题代码。

#!/bin/bash

# get the absolute path of .conf directory
get_conf_dir() {
    local path=$(some_command) || { echo "please install some_command first."; exit 100; }
    echo "$path"
}

# process the configuration
read_conf() {
    local conf_path="$(get_conf_dir)/foo.conf"
    [ -r "$conf_path" ] || { echo "conf file not found"; exit 200; }
    # more code ...
}

read_conf

因此,基本上我想做的是在bash脚本中读取一个简单的配置文件,并且在错误处理方面遇到了一些麻烦。

some_command 是来自第三方库(即coreutils中的greadlink)的命令,该命令是获取路径所必需的。

当运行上面的代码时,我希望它输出“找不到命令”,因为这是发生FIRST错误的地方,但实际上它总是打印“找不到conf文件”。

我对这种行为感到非常困惑,我认为BASH可能打算处理这样的事情,但我不知道为什么。最重要的是,如何解决?

任何想法将不胜感激。

最佳答案

您在任何地方都可以看到please install some_command first消息吗?它是$conf_path行中的local conf_path="$(get_conf_dir)/foo.conf"吗?您的$conf_path值是否为please install some_command first/foo.conf?哪一个未通过-r测试?

不,你没有。 (但是请随时在该$conf_path块中回显exit 200的值以确认这一事实。)(此外,一般来说,错误消息应该发送到标准错误而不是标准输出。因此,它们应该是echo "..." 2>&1。完全不会被普通的命令替换所捕获。)

您之所以不这样做,是因为exit 100块是,从来没有发生过

您也可以在脚本顶部使用set -x看到它。去试试看。

明白了吗?

之所以没有发生,是因为some_command赋值语句吞噬了local path=$(some_command)的失败返回。

尝试运行以下命令:

f() { local a=$(false); echo "Returned: $?"; }; f

您希望看到Returned: 1吗?您可能会看到,但看不到。

您将看到的是Returned: 0

现在尝试以下任一版本:
f() { a=$(false); echo "Returned: $?"; }; f
f() { local a; a=$(false); echo "Returned: $?"; }; f

首先获得您期望的输出?

对。 localexport以及declaretypeset是自己的语句。它们有自己的返回值。他们忽略(并替换)在其上下文中执行的命令的返回值。

您的问题的解决方案是拆分local pathpath=$(some_command)语句。

http://www.shellcheck.net/捕获了此错误(以及许多其他常见错误)。你应该让它成为你的 friend 。

除了上述内容(如果您到目前为止已经设法完成)以外,即使到目前为止已提及更改,您的exit 100也不会退出主脚本,因为它只会退出由任务替换中的命令替换产生的子 shell 。

如果您想让exit 100退出脚本,则您需要注意并重新退出脚本(在get_conf_dir分配后检查conf_path是否失败,并使用先前的退出代码退出),或者删除get_conf_dir函数本身,然后直接内联read_conf

关于bash - 使用$(func)调用有问题的函数时,Bash脚本不会在第一次 “exit”调用时退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31522274/

相关文章:

c - Main 中函数类型之前的预期表达式

php - 从表单按钮调用 PHP 函数

python-3.x - 使用resample时出错,即使我曾经使用过to_datetime和set_index, 'only valid with datetimeindex'还是说

php - 上传/检索图像到mysql数据库

error-handling - 防止错误: “NotAuthenticated: Strategy jwt is not permitted”

linux - SSH 命令在 Expect 脚本中的行为有所不同

mysql - 在 bash 中执行命令时出错

bash - OS X bash 脚本 WHILE 循环中的多个条件

linux - sudo: (whatever): 在 RHEL 5.8 上找不到命令

c++ - C++ 中的对象工厂字典