【问题标题】:log.Println not working with os.Exit(1) for makefilelog.Println 不适用于 os.Exit(1) 生成文件
【发布时间】:2022-08-11 05:55:11
【问题描述】:

我在 Go 中有一个命令行工具,例如:

err := doSomething()
if err != nil {
    log.Println(err) //fmt.Println(err)
    os.Exit(1)
}

在里面生成文件, 我在做:

V = 0
Q = $(if $(filter1, $V),,@)
.PHONY: dosomething
dosomething: ; $(info $(shell printf \"running dosomething\")) @
    $Q cd $(BASE) && ret=0 \\
          test -z \"$$($(dosomething))\" || ret = 1 ; \\
       exit $$ret

制作使用fmt.Println(err) 时失败(如果发生错误),但不打印任何内容。当我使用log.Println 时,它会打印错误但制作继续。如何失败制作以及打印错误?另外,在golang代码中panic()的情况下该怎么办?

    标签: go makefile


    【解决方案1】:

    我根本不明白这个makefile。 $(info $(shell printf "running dosomething")) 应该做什么?为什么不只是$(info running dosomething)?一般来说,你永远不想在配方中使用 make 的 shell 函数,它只会导致混乱。

    其次,您的格式似乎是错误的,因为您将 @ 放在了行尾。

    ret=0 之后还需要一个分号。

    最后,$$($(dosomething)) 应该做什么?您没有将 make 变量 dosomething 设置为任何值,所以这基本上是一个空操作。

    我只能假设在您真正的 makefile 中,您将 make 变量 dosomething 设置为您要运行的命令。提出问题时,提供重现问题的实际文件很有帮助(如果实际文件太大或复杂,则创建一个小型重现案例)。

    在这种情况下,混淆的原因很容易;当您在 shell 中运行 $(dosomething) 时,它会运行 dosomething 程序并捕获其标准输出并扩展为该字符串......所以输出未打印.它被捕获了。例如:

    $ echo hi
    hi
    $ foo=$(echo hi)
    $ echo $foo
    hi
    

    注意hi 没有在第二个命令中打印,因为它被捕获并存储在foo 变量中。

    另一方面,$(...) 不捕获 stderr,仅捕获 stdout:

    $ echo hi 1>&2
    hi
    $ foo=$(echo hi 1>&2)
    hi
    $ echo $foo
    

    请注意,hi 已打印(到标准输出)而不是被捕获(因此 foo 现在为空)。

    我对 Go 不太了解,但我只能假设您显示的两个函数之一打印到 stdout,另一个打印到 stderr。

    您不想捕获任何输出并进行比较,而是想比较程序的退出代码。你可以这样做:

    V = 0
    Q = $(if $(filter1, $V),,@)
    .PHONY: dosomething
    dosomething = <command-to-run>
    dosomething:
            $(info running dosomething)
            $Q cd $(BASE) && $(dosomething)
    

    这允许dosomething 命令的输出在不捕获任何输出的情况下运行,并且它将以命令的退出代码退出,成功时该代码为 0,错误时为非 0(在您的情况下为 1)。

    【讨论】:

      猜你喜欢
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多