无法使用环境变量使用 Powershell 过滤目录
Cannot filter Directories with Powershell using an environment variable
我在尝试过滤环境变量数组中设置的目录列表时遇到意外行为。
当我 运行 此代码使用局部变量时,我得到了预期的结果:
$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
但是,当我用环境变量 $env:yourList
替换 $myList
时
$myPath = "C:\temp\"
$env:yourList = 'Folder1', 'Folder2', '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
一个环境变量总是一个单个字符串,所以你不能存储arrays 其中(或 [string]
以外的任何其他数据类型)。
- 注意:这不在 PowerShell 的控制范围内:环境变量是一个 system-level 功能。
PowerShell stringifies assignment[1] 上的输入数组,这意味着加入以 space 作为分隔符的数组元素(或者,如果已定义,分隔符存储在首选项变量 $OFS
中),这就是数组 'Folder1', 'Folder2', 'Folder3'
变成单个字符串
的原因
'Folder1 Folder2 Folder3'
.
如果您确实需要一个 environment 变量来存储您的数组 - 通常只需要将值传递给 子进程 -你必须在赋值上为它选择一个single-string表示,你可以re-convert到reading[=47=上的数组] 变量;例如:
# Assuming the array elements contain no newlines, use newlines
# to separate them.
$env:yourList = ('Folder1', 'Folder2', 'Folder3') -join "`n"
# Later, re-convert the single-string representation to an array.
$env:yourList -split "`n"
[1] 正如 Doug Maurer 指出的那样,这个 自动 to-string 转换 发生在 any RHS 还不是 [string]
类型,例如 $env:yourList = 42
(分配字符串 '42'
)。换句话说:您分配给环境变量的任何内容都会自动转换为(单个)字符串。
我在尝试过滤环境变量数组中设置的目录列表时遇到意外行为。
当我 运行 此代码使用局部变量时,我得到了预期的结果:
$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
但是,当我用环境变量 $env:yourList
$myList
时
$myPath = "C:\temp\"
$env:yourList = 'Folder1', 'Folder2', '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
一个环境变量总是一个单个字符串,所以你不能存储arrays 其中(或 [string]
以外的任何其他数据类型)。
- 注意:这不在 PowerShell 的控制范围内:环境变量是一个 system-level 功能。
PowerShell stringifies assignment[1] 上的输入数组,这意味着加入以 space 作为分隔符的数组元素(或者,如果已定义,分隔符存储在首选项变量 $OFS
中),这就是数组 'Folder1', 'Folder2', 'Folder3'
变成单个字符串
的原因
'Folder1 Folder2 Folder3'
.
如果您确实需要一个 environment 变量来存储您的数组 - 通常只需要将值传递给 子进程 -你必须在赋值上为它选择一个single-string表示,你可以re-convert到reading[=47=上的数组] 变量;例如:
# Assuming the array elements contain no newlines, use newlines
# to separate them.
$env:yourList = ('Folder1', 'Folder2', 'Folder3') -join "`n"
# Later, re-convert the single-string representation to an array.
$env:yourList -split "`n"
[1] 正如 Doug Maurer 指出的那样,这个 自动 to-string 转换 发生在 any RHS 还不是 [string]
类型,例如 $env:yourList = 42
(分配字符串 '42'
)。换句话说:您分配给环境变量的任何内容都会自动转换为(单个)字符串。