我正在创建一个 PowerShell 脚本只是为了备份我的 WSL 发行版,但是当我尝试使用变量运行该命令时,它不起作用,它显示使用文本,就好像我提供了不正确的参数一样。
$DistrosArray1 = (wsl -l --quiet) | where {$_ -ne ""}
$DistrosArray2 = 'Arch', 'Ubuntu-22.04', 'docker-desktop-data', 'docker-desktop'
$CheckArrayDifference = Compare-Object -ReferenceObject $DistrosArray1 -DifferenceObject $DistrosArray2 -PassThru
echo $CheckArrayDifference
# Does not return anything (there is no difference)
foreach ($Distro in $DistrosArray1) {
wsl --export $Distro "$Distro.tar"
# This method is not working
}
foreach ($Distro in $DistrosArray2) {
wsl --export $Distro "$Distro.tar"
# This method is working
}
最佳答案
听起来您遇到了问题 #4607 的复杂情况。 -- wsl.exe
命令输出一些奇怪的损坏的 UTF16 编码,当尝试从 PowerShell(甚至从 WSL 内部)处理它时,这些编码会产生问题。
此问题现已在最新的 WSL 预览版 0.64.0 中修复。 ,但您确实必须“选择加入”修复程序,以便旧的解决方法(例如 @Bender 和我提供的解决方法)不会无意中中断。
简单设置:
$env:WSL_UTF8=1
...在您的代码之前,WSL 将不再吐出“损坏的 UTF16”。
我的回答中的其他示例:
- Why cannot I match for strings from wsl.exe output?
- Powershell - Strange WSL output string encoding
- How to ask WSL to check if the distribution exists, using Bash and
wsl.exe
?
旧解决方案:
让我们简化问题并制作一个不尝试导出的“安全”示例:
$DistrosArray1 = (wsl -l --quiet) | where {$_ -ne ""}
wsl -d $DistrosArray1[0]
结果:
There is no distribution with the supplied name.
我已经成功使用this comment中的方法来处理它。对于这个特定的例子:
$console = ([console]::OutputEncoding)
[console]::OutputEncoding = New-Object System.Text.UnicodeEncoding
$DistrosArray1 = (wsl -l --quiet) | where {$_ -ne ""}
wsl -d $DistrosArray1[0]
这将正确运行列表中的第一个发行版。
使用以下命令重置编码:
[console]::OutputEncoding = $console
对于大多数非交互式脚本来说这不应该是问题,因为它只是“包装器”的最后一行,但如 @BendertheGreatest评论中指出,这是关键一步。
关于powershell - powershell 中的脚本无法使用数组变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72323974/