问题描述
当尝试过滤环境变量数组中设置的目录列表时,遇到了意外的行为。
当我使用局部变量运行此代码时,我得到了预期的结果:
$myPath = "C:\temp\"
$myList = 'Folder1', 'Folder2', 'Folder3'
Write-Host "myList: $myList"
Get-ChildItem -Recurse $myPath | Where-Object { $_.PSIsContainer } | Where-Object { $_.Name -in $myList } | Select-Object FullName
即
myList: Folder1 Folder2 Folder3
FullName
--------
C:\temp\Folder1
C:\temp\Folder2
C:\temp\Folder3
但是,当我将$myList
替换为环境变量$env:yourList
$myPath = "C:\temp\"
$env:yourList = 'Folder1', 'Folder3'
Write-Host "yourList: $env:yourList"
Get-ChildItem -Recurse $myPath | Where-Object { $_.PSIsContainer } | Where-Object { $_.Name -in $env:yourList } | Select-Object FullName
Get-ChildItem的结果为空
yourList: Folder1 Folder2 Folder3
.
从上面的输出中可以看到,在$env:yourList
中设置的值与在$myList
中设置的值打印相同,因此环境变量的特殊之处是它们在Where-Object标准中以不同的方式处理?
顺便说一句,当使用-Include
而不是Where-Object
时,会发生相同的行为,即:
Get-ChildItem -Path $myPath -Recurse -Include $env:yourList -Directory
解决方法
环境变量始终是单个字符串 ,因此您不能在其中存储 array (或任何其他数组) [string]
以外的其他数据类型。
- 注意:这超出了PowerShell的控制范围:环境变量是系统级功能。
PowerShell 对赋值 [1] 上的输入数组进行字符串化,这意味着使用空格作为分隔符将数组元素连接起来(或者,如果已定义,则分隔符存储在首选项变量$OFS
中,这就是为什么数组'Folder1','Folder2','Folder3'
变成单个字符串的原因'Folder1 Folder2 Folder3'
。
如果您确实确实需要一个 environment 变量来存储您的数组-通常仅在将值传达给子进程时才需要-您必须选择一个-在 assignment 上的字符串表示形式,您可以在 reading 变量上将其重新转换为数组;例如:
# Assuming the array elements contain no newlines,use newlines
# to separate them.
$env:yourList = ('Folder1','Folder3') -join "`n"
# Later,re-convert the single-string representation to an array.
$env:yourList -split "`n"
[1]正如Doug Maurer所指出的那样,此自动字符串转换与 any 尚未为{ {1}},例如[string]
(分配字符串$env:yourList = 42
)。换句话说:您分配给环境变量的任何内容都会自动转换为(单个)字符串。