GNU Make 和 Windows Powershell:"Remove-Item -ErrorAction Ignore" 不起作用

GNU Make and Windows Powershell : "Remove-Item -ErrorAction Ignore" does not work

我正在 Windows PowerShell 控制台中将 Makefile(在 linux bash 中工作)转换为 运行。我使用 GNU Make 4.2.1。我在将 rm bash 命令转换为等效的 PowerShell
时遇到问题 例如,在这个简单的 makefile

clean: powershell " Remove-Item -ErrorAction Ignore aaa.txt" powershell " Remove-Item -ErrorAction Ignore bbb.txt"

如果 aaa.txt 不存在,即使使用 ErrorAction 标志 Ignore 也会引发错误,显然,第二个操作(删除 bbb.txt)不是执行。打印以下消息 make: *** [makefile:2: clean] Error 1

为什么它不起作用?(我读到 Ignore 不会将错误消息添加到 $Error 自动变量)

我必须在 Remove-Item 命令中使用哪个选项?

供参考,如果我 运行 以下 mybat.bat 文件,它可以完美运行,即使aaa.txt 文件不存在,bbb.txt 文件被删除。

powershell " Remove-Item -ErrorAction Ignore aaa.txt"
powershell " Remove-Item -ErrorAction Ignore bbb.txt"

Rq : powershell " Remove-Item -ErrorAction Ignore aaa.txt, bbb.txt" 在这种简单的情况下有效,但这不是一个好的解决方案,因为我使用的 makefile 会调用不同目录中的许多 makefile。

我对 PowerShell 一无所知,但 make 不关心调用的命令打印的文本是什么。它关心退出代码。

根据您的经验,如果文件不存在,PowerShell Remove-Item 似乎仍然以非 0(失败)退出代码退出,而 Ignore 操作只是告诉它不存在打印错误。

请注意,您的批处理文件不是 make 所做的。它的作用更像是:

powershell " Remove-Item -ErrorAction Ignore aaa.txt"
if ERRORLEVEL 1 <fail>

如果你想让 make 忽略错误并继续,你可以使用 the - prefix 作为配方行:

clean:
        -powershell " Remove-Item -ErrorAction Ignore aaa.txt"
        powershell " Remove-Item -ErrorAction Ignore bbb.txt"

提供了有用的背景信息和 PowerShell 外部 的实用解决方法。

关于为什么PowerShell报告退出码1:

  • 当使用带有(隐含的)-Command 参数的 CLI 时,它是(最后)语句的成功状态,反映在布尔自动变量 $? 中,即映射到退出代码 0 ($true) 和 1 ($false).

  • Remove-Item -ErrorAction Ignore aaa.txt 的故意 沉默 失败令人惊讶地反映在 $? 作为 $false 尽管如此,导致退出代码 1.

解决方法(如果问题需要从 PowerShell 中解决):

在最简单的情况下,附加 ; $null(转义为 ; $null 以便在 Makefile 中使用):

clean:
    powershell "Remove-Item -ErrorAction Ignore aaa.txt; $$null"
    powershell "Remove-Item -ErrorAction Ignore bbb.txt; $$null"

通过 CLI 输出 $null 是安静、成功的无操作,将退出代码重置为 0

另一个选项 - 仅适用于 v6.x - 是将命令括在括号中:

clean:
    powershell "(Remove-Item -ErrorAction Ignore aaa.txt)"
    powershell "(Remove-Item -ErrorAction Ignore bbb.txt)"

(...) 将一个命令变成一个表达式,这个表达式本身被认为是成功的,即使包含的命令报告一个(非终止)错误,它将 $? 重置为 $true 因此导致退出代码 0.
请注意,这种行为也令人惊讶,如 this GitHub issue, which is why it was changed in v7.0, to better support && and ||, the pipeline-chain operators

中所讨论