js2010 的回答 https://stackoverflow.com/a/66160252/45375显示有效的解决方案:使用"..."
- 引用,即可扩展字符串 https://stackoverflow.com/a/40445998/45375 明确地.
养成使用是一个好习惯"..."
明确地 around 命令参数那是字符串含有变量引用(例如"$HOME/projects"
) 或子表达式(例如,"./folder/$(Get-Date -Format yyyy-MM)"
)
While such compound string arguments generally do not require double-quoting[1] - because they are implicitly treated as if they were "..."
-enclosed - in certain cases they do, and when they do is not obvious and therefore hard to remember:
这个答案 https://stackoverflow.com/a/41254359/45375详细说明了令人惊讶的复杂规则,但以下是如果你这样做的话,有两个值得注意的陷阱not use "..."
:
-
如果一个复合参数以。。开始子表达式 ($(...)
),其输出通过作为一个单独的论点; e.g. Write-Output $(Get-Location)/folder
passes two论点Write-Output
: 的结果$(Get-Location)
和字面意思/folder
-
如果一个复合参数以。。开始变量引用and后面跟着什么语法上看起来像(a) 一个财产访问权 (e.g., $PSVersionTable.PsVersion
) 或 (b) a方法调用 (e.g., $PSHome.Tolower()
) it is 就这样执行,即作为表达(而不是被视为变量引用后跟文字部分)。
-
除了#1:这样的论点不一定是string,但无论属性值或方法调用返回值是什么数据类型。
-
Aside #2: A compound string that starts with a quoted string (whether single- or double-quoted) does not work, because the quoted string at the start is also considered an expression, like property access and method calls, so that what comes after is again passed as separate argument(s). Therefore, you can only have a compound strings consisting of a mix of quoted and unquoted substrings if the compound string starts with an unquoted substring or a non-expression variable reference.[2]
后者是这个案例中发生了什么:
-
Unquoted $env:computername.csv
被解释为尝试访问一个名为csv
关于存储在(环境)变量中的对象$env:computername
,并且自从[string]
存储在那里的实例没有csv
属性,表达式计算为$null
.
-
By forcingPowerShell 通过以下方式将此值解释为可扩展字符串"..."
, 通常插值规则 https://stackoverflow.com/a/40445998/45375适用,这意味着.csv
确实被视为literal(因为属性访问需要使用$(...)
在可扩展字符串中)。
[1] Quoting is required for strings that contain metacharacters such as spaces.
For values to be treated verbatim, '...'
quoting is the better choice (see the bottom section of this answer https://stackoverflow.com/a/55614306/45375 for an overview of PowerShell string literals).
Also, using neither double- nor single-quoting and individually `
-escaping metacharacters is another option (e.g. Write-Output C:\Program` Files
.
[2] For instance, Write-Output a"b`t"'`c'
and Write-Output $HOME"b`t"'`c'
work as intended, whereas Write-Output "b`t"'`c'
and Write-Output $HOME.Length"b`t"'`c'
do not (the latter two each pass 3 arguments). The workaround is to either use a single "..."
string with internal `
-escaping as necessary (e.g. Write-Output "${HOME}b`t``c"
) or to use string-concatenation expression with +
enclosed in (...)
(e.g. Write-Output ($HOME + "b`t" + '`c')
)