首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Bash和`wsl.exe`要求WSL检查发行版是否存在?

如何使用Bash和`wsl.exe`要求WSL检查发行版是否存在?
EN

Stack Overflow用户
提问于 2022-06-26 20:06:09
回答 1查看 228关注 0票数 0

我试图要求WSL检查发行版是否存在,例如,wsl.exe -l -v输出:

代码语言:javascript
复制
  NAME                   STATE           VERSION
  Arch-Linux             Running         2
* Ubuntu                 Running         2
  docker-desktop         Running         2
  docker-desktop-data    Running         2

我需要要求WSL检查desktop-desktop-dataArch是否存在。

这是我的小巴什代码。我用了几种不同的方法测试,但都没有用。

代码语言:javascript
复制
# 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-27 00:50:07

更新答复

在最新的WSL预览版(0.64.0)中,这个问题背后的核心问题已经得到了解决,或者至少得到了改进,但是请注意,这是目前只有Windows 11用户才能使用的。

为了避免破坏依赖(或解决此问题)的旧代码,修复方法是选择加入。设置一个WSL_UTF8环境变量的值为1 (仅在我的测试中,该值)将导致来自wsl.exe的正确/预期的输出。

请注意,如果在WSL中使用此环境变量,则还需要将其添加到WSLENV,以便通过互操作将其“传回”到Windows。

例如,对于您的使用,下面的内容现在可以使用了:

代码语言:javascript
复制
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安装

简短答覆:

代码语言:javascript
复制
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"

解释

在你的例子中,有几件事情发生了:

  • 首先,最让您感到困扰的是一个WSL错误(在这个问题中有更详细的介绍),它会导致输出采用错误的UTF-16编码。在某种程度上,您可以在wsl.exe | hexdump -C中看到这一点,它将在每个规则字符之后显示空字节字符。 该部分的解决方案是通过iconv -f utf16运行它。例如: wsl.exe -l -v _ iconv -f UTF-16

我猜您可能在试图解决前面的错误时,在代码中引入了以下一些错误:

  • $wsl_distro_namegrep中有单引号,这将禁用Bash中的字符串内插。你需要双引号。
  • 由于在^输出的前几个字符中有空格(和/或星号),wsl.exe -l -v将无法在正则表达式的开头工作。最好使用"\s$wsl_distro_name\s查找被空格包围的发行版名称。 这也将阻止表达式找到“部分”分发名。没有它,“停靠桌面”将匹配“停靠桌面”和/或“停靠桌面数据”。
  • grep -q禁用输出,只有找到时返回0的状态代码,如果没有返回状态代码,则返回1。由于您试图将grep输出捕获到$wsl_command中,因此结果将始终为空。您可以删除-q以捕获输出,或者继续使用-q并测试状态代码。
  • 考虑到您的if语句,您似乎希望输出无论如何都是状态结果,但是测试"$wsl_command"不会对此起作用,也不会通过backticks捕获输出。看起来更像是: Wsl_distro_name=“docker-桌面-data”wsl.exe -l -v _康涅v -f UTF-16 \s${wsl_distro_name}\s如果[ $?-eq 0 ];然后回波找到fi $?变量保存最后一个命令的退出代码。 另一种选择是: Wsl_distro_name=“docker-桌面-data”wsl_distro_result=$(wsl.exe -l -v -f -f -o“s ${wsl_distro_name} s${wsl_distro_name}s”。*“awk '{print $2}')如果[ -n”"$wsl_distro_result“,则回显”发现${wsl_distro_name},它是${wsl_distro_result}“。否则回显"${wsl_distro_name}未找到“。fi 注意,我在这个片段中将-o选项添加到grep中。默认发行版将在第一个字段中有一个星号,这意味着我们需要“规范化”它,以便awk的第二个字段总是状态。
  • 最后,建议使用$()而不是回退。请参阅这个问题,但请注意POSIX规范说,“不建议使用引用过的各种命令替换。”
  • 附带注意:如果出于某些原因,您需要在阿尔卑斯山中运行这个程序包,那么请确保安装gnu-libiconv包,以便iconv也能正确地处理这个问题。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72764797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档