我有一个用于 Windows 设置的 Makefile(使用 Powershell 而不是 Bash),并且我正在尝试在其中输入多行命令。
例如:
SHELL := pwsh.exe
.SHELLFLAGS := -Command
...
clean-all:
@if ( Test-Path ${OUTPUT_FOLDER} ) { ` \
(Remove-Item -Recurse -Force -Path "${OUTPUT_FOLDER}") ` \
}
Poweshell 中的多行命令可以使用
`
符号编写,Makefile 中的多行脚本可以使用 \
编写。它们之间似乎存在冲突,因为我尝试使用 \n
、`
、` \
、\
作为行尾,但没有任何效果。
我收到如下错误:
Unexpected token '\' in expression or statement.
在线(Remove-Item -Recurse -Force -Path "${OUTPUT_FOLDER}") ` \
\
是PS中的特殊字符,如果需要,需要正确转义。
例如:
'Hello\Hi' -replace '.*\'
# Results
<#
The regular expression pattern .*\ is not valid.
At line:1 char:1
+ "Hello\Hi" -replace '.*\'
#>
'Hello\Hi' -replace '.*\\'
# Results
<#
Hi
#>
不管怎样,如果你这样做会发生什么?我没有任何东西可以用 makefile 运行,所以,我无法测试这个。
SHELL := pwsh.exe
.SHELLFLAGS := -Command
...
clean-all:
@if ( Test-Path ${OUTPUT_FOLDER} ) { ` \ `
(Remove-Item -Recurse -Force -Path "${OUTPUT_FOLDER}") ` \
}
我更喜欢在windows中使用powershell作为make的默认shell,尤其是在Windows中。您应该注意,制作零食
\
的定义和配方有所不同。
FOO := hello \
world
解析此定义时,make 将丢弃
\
,并将 hello
和 world
连接起来,然后 FOO
将是 hello world
。
然而,在食谱中,事情就变得不同了。在像 bash 这样的 shell 中,
\
通知 bash 内容将出现在下一行。由于 make 最初是为类似 bash 的 shell 设计的,因此 make 没有必要丢弃 \
并连接 \
字符之前和之后的字符串。
bar:
echo hello \
world
例如,这里 make 会简单地将
echo hello \
、\n
(隐藏的新行)和 world
传递给 shell,即使实际的 shell(例如 powershell)不会以类似的方式处理 \
用bash。
一个可能的解决方法是利用 powershell 的注释块,即
<# foo bar #>
,而不是行注释。
# Powershell will stop parsing when it gets the '#' character since
# comments are not important,so anything follows '#' are ignored
# thus powershell will complain that "world" is not executable or a command
all:
Write-Host hello #\
world
SHELL := pwsh.exe
.SHELLFLAGS = -NoProfile -Command
# OK, powershell needs to known where the comment block ends
# the new line character and \ is inside the comment block, so they have no effect
all:
Write-Host hello <#\
#>world
通过将
\
放在注释块中,可以防止 powershell 误解 \
并连接两个参数。 Make 会将 Write-Host hello <#\\n#>world
传递给 powershell。
如果你想在 makefile 中使用 bash 中具有特殊含义的 `,则需要使用转义形式
\
`。
# powershell needs to know where the comment block ends
# so it will keep parsing when it gets '<#', thus getting the ` correctly
# and, better still, since everything is inside the comment block,
# these characters inside the comment block will have no effect
all:
Write-Host hello <#\'\
#> world
但是由于注释块中的新行最终会被忽略,即
<# \n #>
,所以分散在两行中的字符串会自动连接起来。不需要使用`来通知powershell应该连接内容。
总之,一个简单的评论块
<# \ \n #>
就足够了。希望这能解决您的问题。顺便说一句,英语不是我的母语,对于潜在的错误措辞感到抱歉。