我试图要求WSL检查分布是否存在,例如,wsl.exe -l -v
输出:
NAME STATE VERSION
Arch-Linux Running 2
* Ubuntu Running 2
docker-desktop Running 2
docker-desktop-data Running 2
我需要让WSL检查desktop-desktop-data
或Arch
是否存在。
这是我的小Bash代码。我用几种不同的方法进行了测试,都没有效果。
# Distribution name: Ubuntu
wsl_distro_name="docker-desktop"
# WSL command to find the distribution name
wsl_command=`wsl.exe -l -v | grep -iq '^$wsl_distro_name' | awk '{print $2}'`
if [[ "$wsl_command" ]]; then
echo "Distro found"
exit 0
else
echo "Not found"
exit 1
fi
更新答案:
这个问题背后的核心问题已经修复,或者至少在最新的WSL预览版本(0.64.0)中得到了改进,但请注意,这目前仅适用于Windows 11用户。
为了避免破坏依赖(或绕过)该问题的旧代码,修复是可选的。将WSL_UTF8
环境变量设置为1
(在我的测试中,只有该值)将导致wsl.exe
的正确/预期输出。
WSLENV
中,以便它被传递回"
对于您的使用,例如,现在可以使用以下命令:
export WSL_UTF8=1
WSLENV="$WSLENV":WSL_UTF8
wsl_distro_name="docker-desktop-data"
wsl.exe -l -v | grep -q "s${wsl_distro_name}s" && echo "Found" || echo "Not found"f
对于旧的WSL安装
短答:
wsl_distro_name="docker-desktop-data"
wsl.exe -l -v | iconv -f UTF-16 | grep -q "s${wsl_distro_name}s" && echo "Found" || echo "Not found"
解释:
在你的例子中有一些事情要做:
首先,最可能阻碍您的事情是wsdl错误(在本问题中更详细地讨论),该错误导致输出使用混乱的UTF-16编码。在某种程度上,您可以通过
wsl.exe | hexdump -C
看到这一点,它将在每个常规字符之后显示空字节字符。该部分的解决方案是通过
iconv -f utf16
运行它。例如:wsl.exe -l -v | iconv -f UTF-16
我猜您可能在尝试解决前面的错误时,在代码中引入了以下一些错误:
您的
grep
中有单引号中的$wsl_distro_name
,它在Bash中禁用字符串插值。这里需要双引号^
不会在正则表达式的开始工作,因为在wsl.exe -l -v
输出的前几个字符中有空白(和/或星号)。最好使用"s$wsl_distro_names
来查找被空格包围的发行版名称。这也将防止表达式找到"partial"分布的名字。没有它,"docker-desktop";将匹配"docker-desktop";和"docker-desktop-data"。
grep -q
禁用输出,当找到0
或未找到1
时只返回状态码。由于您试图将grep输出捕获到$wsl_command
中,因此结果将始终为空。您可以删除-q
以捕获输出,或者继续使用-q
并测试状态代码。给定您的
if
语句,似乎您可能期望输出是状态结果,但测试"$wsl_command"
不会为此工作,也不会通过反引号捕获输出。它看起来更像:wsl_distro_name="docker-desktop-data" wsl.exe -l -v | iconv -f UTF-16 | grep -q "s${wsl_distro_name}s" if [[ $? -eq 0 ]]; then echo Found fi
$?
变量保存了最后一个命令的退出码。另外:
wsl_distro_name="docker-desktop-data" wsl_distro_result=$(wsl.exe -l -v | iconv -f UTF-16 | grep -o "s${wsl_distro_name}s.*" | awk '{print $2}') if [[ -n "$wsl_distro_result" ]]; then echo "Found ${wsl_distro_name} and it is ${wsl_distro_result}." else echo "${wsl_distro_name} not found." fi
注意,我在该代码片段中向
grep
添加了-o
选项。默认分布将在第一个字段中有一个星号,这意味着我们需要"规范化"。使awk
的第二个字段始终是Status.最后,建议使用
$()
而不是反引号。请参阅这个问题,但请注意POSIX规范说,"不建议使用反引号括起的各种命令替换。">旁注:如果出于某种原因,您需要在Alpine中运行此操作,那么请确保安装
gnu-libiconv
包,以便iconv
也能正确处理此操作。