【问题标题】:Make: how to continue after a command fails?Make:命令失败后如何继续?
【发布时间】:2011-02-09 20:07:51
【问题描述】:

命令$ make all 给出了诸如rm: cannot remove '.lambda': No such file or directory 之类的错误,因此它停止了。我希望它忽略 rm-not-found-errors。如何强制制作?

生成文件

all:
        make clean
        make .lambda
        make .lambda_t
        make .activity
        make .activity_t_lambda
clean:
        rm .lambda .lambda_t .activity .activity_t_lambda

.lambda:
        awk '{printf "%.4f \n", log(2)/log(2.71828183)/$$1}' t_year > .lambda

.lambda_t:
        paste .lambda t_year > .lambda_t

.activity:
        awk '{printf "%.4f \n", $$1*2.71828183^(-$$1*$$2)}' .lambda_t > .activity

.activity_t_lambda:
        paste .activity t_year .lambda  | sed -e 's@\t@\t\&\t@g' -e 's@$$@\t\\\\@g' | tee > .activity_t_lambda > ../RESULTS/currentActivity.tex

【问题讨论】:

    标签: makefile


    【解决方案1】:

    试试-i 标志(或--ignore-errors)。顺便说一句,The documentation 似乎提出了一种更强大的方法来实现这一点:

    要忽略命令行中的错误,请在行文本的开头(在初始制表符之后)写一个-。在将命令传递给 shell 执行之前,- 被丢弃。

    例如,

    clean:
      -rm -f *.o
    

    这会导致rm 继续,即使它无法删除文件。

    所有示例都使用rm,但适用于您需要忽略错误的任何其他命令(即mkdir)。

    【讨论】:

    • 不要这样做!你不应该忽略错误。只需将 -f 标志添加到 rm ,尝试删除不存在的文件时将不再失败。但是,如果它确实无法删除文件,它仍然会返回并出错。这就是你想要的行为,有问题就失败!
    • @Kristof Provost 同意。 rm -f 更适合用户遇到的特定问题,但即使有时不安全,了解通用解决方案仍然很高兴。
    • Make 还提供了$(RM),您可以使用它来代替rm -f
    【解决方案2】:

    make -k(或 gnumake 上的--keep-going)会满足你的要求,我想。

    您确实应该找到失败的 del 或 rm 行并在其中添加 -f 以防止该错误发生在其他人身上。

    【讨论】:

    • 我不想说什么,但我也想知道他们的想法。如果出于某种原因我不明白为什么该标志不合适,那么提出来将是一件好事。
    • 您不应忽略错误。 Brian、Oded 和 NebuSoft 提出的解决方案是正确的。这个和公认的答案是错误的。
    • @KristofProvost - 啊。我猜很公平。一般来说,我也相信找到问题根源的答案优于仅仅回答所提问题的答案(比如这个)。我不确定我是否会为此否决某人,但不同的笔触......
    • 不错的答案。它包含一个简单的顶级标志,没有其他答案包含,但仍然推荐正确的行为。错误不应被忽略,但了解选项是件好事。
    • 一些有用的事情是忽略编译器错误...这允许make 构建尽可能多的编译单元,同时您可以修复编译器阻塞的任何问题。这样,当您修复了所有损坏的部分时,您不必等待其他所有部分也都构建好。
    【解决方案3】:

    通过使用true 命令在管道后面阻止rm 的返回码成功返回,该命令始终返回0(成功)

    rm file || true
    

    【讨论】:

    • 您也可以使用rm file || true。这样,如果rm 返回错误代码,就会调用true。但是rm 可能产生的任何控制台输出都不会被管道吞没。
    • 我什至会说你应该使用` ||当您的真正意图不是通过管道stdout时为true`。
    • 我想这一直是一个错字。由于这是这个问题的规范并且这个答案得到了高度评​​价,因此我修正了错字以推荐正确和惯用的用法,而不是混淆和意外(但实际上是巧合工作)的原始代码。
    【解决方案4】:

    把干净改成

    rm -f .lambda .lambda_t .activity .activity_t_lambda
    

    即不提示删除;如果文件不存在,请不要抱怨。

    【讨论】:

      【解决方案5】:

      要让 make 实际上忽略单行上的错误,您可以简单地在其后缀 ; true,将返回值设置为 0。例如:

      rm .lambda .lambda_t .activity .activity_t_lambda 2>/dev/null; true
      

      这会将 stderr 输出重定向到 null,并在命令之后返回 true(始终返回 0,使 make 相信命令成功而不管实际发生了什么),从而允许程序流程继续。

      【讨论】:

      • 这适用于前导破折号不适用的情况(我得到了一个生成文件来运行需要失败的测试,稍后将解析日志)
      【解决方案6】:

      在您的rm 命令中添加一个-f 选项。

      rm -f .lambda .lambda_t .activity .activity_t_lambda
      

      【讨论】:

        【解决方案7】:

        更改您的clean,以便rm 不会抱怨:

        clean:
            rm -f .lambda .lambda_t .activity .activity_t_lambda
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-06-05
          • 2020-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-08
          相关资源
          最近更新 更多