【问题标题】:How to write commands in conditions like if statements?如何在 if 语句等条件下编写命令?
【发布时间】:2017-12-19 06:56:33
【问题描述】:

我想将命令编写为 if 的条件语句,即,当命令执行没有任何错误时,它应该打印成功,如果失败则打印失败。 我什至试图阻止打印命令的长控制台消息。 以下是我正在使用的代码,它可以完美运行,无需任何条件语句,例如打印成功或失败消息。

$(BASENAME).pdf: $(BASENAME).ps
    ps2pdf $(BASENAME).ps $(BASENAME).pdf  

$(BASENAME).ps: $(BASENAME).dvi
    dvips -Ppdf $(BASENAME).dvi -o $(BASENAME).ps

我试着把上面改成

$(BASENAME).pdf: $(BASENAME).ps
    @out=ps2pdf $(BASENAME).ps $(BASENAME).pdf > /dev/null 2>&1 && echo "    5. ps2pdf successful" || echo "    5. ps2pdf failed"

$(BASENAME).ps: $(BASENAME).dvi

    dvips -Ppdf $(BASENAME).dvi -o $(BASENAME).ps  > /dev/null 2>&1\
    if [ $? -eq 0 ];\
            then \
            echo "    4. dvips successful";\
    else \
            echo "    4. dvips failed";\
            exit 2;\
    fi

这导致我的执行失败并在运行代码时出现错误,如下面的错误

dvips -Ppdf basename_04.dvi -o basename_04.ps \
if [ basename_04.dvi -eq 0 ];\
        then \
        echo "    4. dvips successful";\
else \
        echo "    4. dvips failed";\
        exit 2;\
fi
/bin/sh: -c: line 2: syntax error near unexpected token `then'
/bin/sh: -c: line 2: `      then \'
make: *** [basename_04.ps] Error 1

即使用分号更新后,我也遇到了错误。

dvips -Ppdf nkukunur_04.dvi -o nkukunur_04.ps  > /dev/null 2>&1 ;\
      if [ nkukunur_04.dvi -eq 0 ]; \
              then \
              echo "    4. dvips successful"; \
      else \
              echo "    4. dvips failed"; \
              exit 2; \
      fi
/bin/sh: line 1: [: nkukunur_04.dvi: integer expression expected
    4. dvips failed

请帮我解决这个问题。

【问题讨论】:

    标签: linux makefile


    【解决方案1】:

    您缺少一个分号 - 和一个双美元:

    $(BASENAME).ps: $(BASENAME).dvi
        dvips -Ppdf $(BASENAME).dvi -o $(BASENAME).ps; \
        if [ $$? -eq 0 ]; \
                then \
                echo "    4. dvips successful"; \
        else \
                echo "    4. dvips failed"; \
                exit 2; \
        fi
    

    缺少的分号是第一个命令行末尾的分号($(BASENAME).ps 之后和反斜杠之前)。假设make 将反斜杠换行符替换为空白(不是换行符)。这就是为什么您需要在测试后使用分号;这就是为什么在if 之前也需要一个。

    双美元是必需的,因为$? 是一个 Make 宏,但您希望 shell 能够查看和解释 $?。因此,您使用 $$ 将其从 Make 中隐藏,这是一个扩展为 $ 的宏调用。

    【讨论】:

    • 即使在修复了错误之后,我也收到了我在问题中更新的错误。
    • 看到更新后的问题,我已经更新了答案。
    • 如果它给出一个错误,它是打印 dvips 失败,现在可以正常工作了。但退出2;没有破坏/退出下一个规则的执行。你能在这方面帮助我吗?
    • 单独获取,makefile 的那个片段导致 make 检测到命令以状态 2 退出并停止进一步处理(并以状态 2 退出)。因此,尚不清楚您正在做什么以使其继续。你可以使用make -k;你可能在makefile 中有一个.IGNORE: 目标;可能还有其他东西可以让它继续。
    【解决方案2】:

    所以,我不知道使用 conditional directives 与使用普通 Bash 条件的最佳做法是什么,就像您正在做的那样。但是要修复您的代码,请删除第一行之后的反斜杠:

    dvips -Ppdf $(BASENAME).dvi -o $(BASENAME).ps <<<< removed backslash
    if [ $? -eq 0 ];\
            then \
            echo "    4. dvips successful";\
    else \
            echo "    4. dvips failed";\
            exit 2;\
    fi
    

    否则所有行都作为单个 bash 语句执行:直到分号的 if 作为参数传递给 dvipsthen 开始一个新语句,因此出现意外的令牌错误。

    【讨论】:

    • 如何从 make 文件中退出以继续进行下一步。我尝试了出口 2;但它没有用。
    • 改用pkill -9 make我不知道答案。
    • 这只适用于 GNU Make 和 .ONESHELL 指令。反斜杠的存在是有充分理由的,但它前面需要一个分号。
    猜你喜欢
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 2022-11-29
    • 2016-08-17
    • 1970-01-01
    • 2016-06-28
    • 2014-07-14
    相关资源
    最近更新 更多