批处理脚本 FOR 循环只设置输出的第一个字母 wsl --list -q

问题描述 投票:0回答:1

我正在编写一个批处理脚本,将文件从我的 Windows 目录复制到 WSL 发行版。其中一部分是选择将文件复制到哪个发行版。如果我使用命令

wsl --list -q
如果给我以下输出:

Ubuntu-22.04
Ubuntu-18.04

我正在尝试使用此处答案中描述的 FOR 循环过程为变量分配发行版名称:How to set commands output as a variable in a batch file

但是,第一个变量始终只是第一行的第一个字母 (U),第二个变量为空。

这就是我一直在尝试的:

@echo off

SETLOCAL ENABLEDELAYEDEXPANSION

SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`wsl --list -q`) DO (
SET "var!count!=%%F"
SET /a count=!count!+1
)

ECHO %var1%
ECHO %var2%
ENDLOCAL

输出:

U
ECHO is off.

我试过删除 USEBACKQ,添加

delims=
,并删除
tokens=*
。我也尝试在发布的答案中使用单变量版本。我仍然只得到 U。如果我将
wsl --list -q
写入 .txt 文件,它会正确写入。我试图避免将这些写入文件只是为了读取它们并删除文件。我想知道
wsl --list
命令的输出是否与其他命令不同。如果我使用不同的命令,例如
dir
.

,变量会正确填充
windows batch-file windows-subsystem-for-linux
1个回答
0
投票

这里有两个步骤:

  • 转换
    wsl --list
    从 UTF-16-LE
  • 的输出
  • 从结果输出中获取发行版本

WSL 的 CLI 没有为第二步提供优雅的解决方案。但是,如果您的 PC 上只有 Ubuntu 映像,那么可以使用

delims=-
轻松标记这些映像,因为它们使用相同的格式命名。但是,处理生成的字符编码是完全不同的故事,因为
cmd.exe
没有提供将文本从一种编码转换为另一种编码的简单方法。也就是说,如果 - 再次 -
wsl --list -q
输出任何东西,那么你确实安装了一些 WSL 发行版,然后你可以访问
iconv
:

@echo off & setlocal EnableDelayedExpansion

set /a distros=0 >nul

for /f "tokens=1,2,* delims=- " %%i in (
    'wsl --list --quiet ^| wsl --exec iconv -f UTF-16LE -t ASCII'
) do (
    if /i "%%~i"=="Ubuntu" if not "%%~j"=="" (
        set /a distros+=1 >nul 2>&1
        if /i "%%~j"=="Ubuntu" (
            set distros[!distros!]=%%~i
        ) else (
            set distros[!distros!]=%%~i-%%~j
        )
    )
)

之后,数组可以像这样使用:

for /l %%i in (1, 1, %distros%) do (
    echo(!distros[%%~i]!
)
© www.soinside.com 2019 - 2024. All rights reserved.