更新:
In PowerShell (Core) 7.1+, file paths passed to the -OutFile
parameter of Invoke-WebRequest
and Invoke-RestMethod
are now interpreted literally:
That is, -OutFile
now acts like -LiteralPath
,[1] and there is no longer a need to escape [
and ]
characters, so that the following example command works as-is:
Invoke-WebRequest http://example.org -OutFile File[1].txt
Therefore, the following applies only to Windows PowerShell (and to now-obsolete PowerShell (Core) versions v7.0 and below):
转义 [
和 ]
字符为 `[
和 `]
,以便在使用 -Path
(-FilePath
) 和 -OutFile
作为 通配符表达式 解释时将它们视为字面量。不幸的是,这种方法目前只有一半起作用,因为底部部分讨论的一个错误:
现在的解决方法:感谢hashbrown帮助简化。
- 使
Invoke-RestMethod
/ Invoke-WebRequest
保存到临时文件中...
- ... 然后将临时文件重命名(移动)为所需的输出文件路径。
$outFile = '.\file[1].txt'
'hi' | Out-File -FilePath ($tempFile = New-TemporaryFile)
Move-Item -Force -LiteralPath $tempFile -Destination $outFile
在Windows PowerShell v4-中,使用[IO.Path]::GetTempfileName()
代替New-TemporaryFile
。
将文字路径转义以用作通配符模式:
使用以下任何字符串文字表示之一,最终将得到具有直接内容file`[1`].txt
的相同字符串,当被解释为通配符表达式时,它是文字字符串file[1].txt
的转义等效形式:
'file`[1`].txt'
"file``[1``].txt"
file``[1``].txt
要通过编程方式创建此转义程序,请使用:
$literalName = 'file[1].txt'
$escapedName = [WildcardPattern]::Escape($literalName)
重要的是目标 cmdlet 在传递给它的
-Path
(
-FilePath
) 参数中将
[
和
]
视为
`
转义,以便它们被视为原义。如果您使用
"..."
引用或未引用的参数(大多数情况下表现得像被包含在
"..."
中),则 PowerShell 的字符串解析会妨碍该过程:在可扩展字符串(
"..."
)内部也使用
`
作为转义字符,因此为了通过
`
,您必须对其进行转义,如
``
。否则,像
`[
这样的内容在
"..."
内部变成了
[
,因为从
"..."
的角度来看,
`[
是一个转义的
[
,而转义不需要转义的字符会变成该字符;简而言之:像
"file`[1`].txt"
和
file`[1`].txt
这样的内容都会变成普通的
file[1].txt
,就好像您从未使用过
`
一样。相比之下,在
'...'
引用的字符串内部,
`
字符以原义使用,不需要转义。
许多 cmdlets 的有缺陷的文件创建行为,包括 -Path
参数:
如上所述的错误 - 在文件创建时误用了转义后的表示法作为文本文件名 - 影响了大部分 cmdlets,不幸的是:它们在创建文件时意外地保留了转义模式中的`
字符,因此通过指定-Path 'file
[1].txt'
,你最终会得到一个名为file`[1`].txt
的文本文件。
幸运的是,大多数 cmdlets确实支持-LiteralPath
,因此使用-LiteralPath file[1].txt
是更好的选择,可以避免这个bug。
受影响的一些cmdlets:
Invoke-WebRequest
和Invoke-RestMethod
Out-File
以及因此也包括重定向运算符>
和>>
,它们在幕后有效地调用了Out-File
。
请注意,Set-Content
和Add-Content
没有展示这个问题。
所有(?)的Export-*
cmdlets。
其他?
该漏洞已经在GitHub issue #9475中报告。
[1] 这实际上是一项破坏性的更改,但由于原始行为的反直觉特性而被认为是可以接受的。不幸的是,这种反直觉的行为在许多其他情况下仍然存在 - 包括仍然使用Out-File
,除非明确使用-LiteralPath
。有关摘要,请参见GitHub问题#17106。
Test-Path -Path 'file\
[1`].txt'` - Theo