Windows Subsystem for Linux (WSL) 功能增强指南

经过长时间的测试阶段,Windows Subsystem for Linux(WSL)终于在Windows 10版本1709中发布了第一个稳定版本。WSL通过Microsoft Store集成和新发行版的逐步发布,似乎正在实现其真正的潜力,随着bug的修复和越来越多的用户开始倾向于使用它而不是多启动系统(但让避免引发Windows与Linux操作系统之争,这不是本文的主题)。

正如可能已经知道的(除非偶然看到这篇文章),WSL默认情况下仍然不允许将SH脚本(.sh文件)关联到bash.exe或wsl.exe(或任何其他Linux可执行文件,如.out和.elf),也不能通过拖放文件和文件夹到脚本来传递它们作为参数。此外,如果是刚从Windows转向Linux的用户,可能会在创建/编辑这些脚本时遇到麻烦。

但不用担心,因为对于前两个问题,解决方案相当简单:一个Windows注册表键!

SH/ELF文件关联和拖放

如果是Windows新手,想知道什么是注册表键(或Windows注册表),并且不是一个懒惰的读者,可以通过点击这里找到所有问题的答案,只会告诉可以通过简单地双击它来安装一个键(或合并它,使用正确的术语);如果问,这非常方便。

所以,如果只是来这里寻求解决方案,下载链接在文章顶部:请记住下载最新版本;除非喜欢bug和缺少功能(无权评判)。

合并注册表键后,只需将bash.exe或wsl.exe设置为打开.sh文件或其他Linux可执行文件(如.elf)的默认程序即可。

该脚本还支持以下特定发行版的可执行文件:ubuntu.exe、SLES-12.exe、openSUSE-42.exe、kali.exe和debian.exe。

注册表键还将启用将文件拖放到脚本/可执行文件上以将它们用作参数的功能,右键单击>以管理员身份运行选项,附带可选的右键单击>用Vim编辑器编辑键,以及额外的右键单击文件夹>在这里打开WSL键。

请注意,现在还可以将任何类型的Linux可执行文件与WSL关联:包括编译代码后创建的.out文件、ELF可执行文件和其他可执行二进制文件。由于Linux操作系统与Windows不同,不需要为这些文件使用扩展名,可以给它们任何扩展名,一个尚未使用的文件扩展名(建议.lxx)或者只是.elf就可以了。

创建和编辑.sh文件

可能会认为这是简单的一步,但会犯错……至少在安装一个好的文本编辑软件之前。事实上,众所周知,Windows记事本是撒旦的化身,在任何情况下都不应该使用它。

开玩笑的,Windows记事本只设计为使用Windows行结尾(\r\n)并且不会识别Unix行结尾(\n),但有很多替代品,如Notepad++,或者个人最喜欢的,程序员记事本。

或者,上面可下载的rar归档文件将提供一个可选的键,以在上下文菜单(文件右键单击)中添加编辑(Linux Vim编辑器)选项。Vim并不是最实用的编辑器,但它可以完成工作(在某些发行版上可能会有bug)。

安装后,只需创建一个new.txt文件,将扩展名更改为.sh,用[不是记事本]打开它,找到文件属性/行结尾(例如:Programmer's Notepad中的文件>属性)并将其更改为Unix行结尾(如果使用Vim,则不需要担心);只需要为新文件这样做。

SH关联脚本的工作原理

将在[HKEY_CLASSES_ROOT\Applications\bash.exe]和[HKEY_CLASSES_ROOT\Applications\wsl.exe]中的键上工作。

首先,让通过在"...\shellex\DropHandler"键中添加DropHandler来启用所有文件的拖放功能;不会走得太远,以至于创建一个新的拖放处理程序,所以将只使用vbs文件的拖放处理程序:{60254CA5-953B-11CF-8C96-00AA00B8708C}。

"...\shell\open\command"键的Windows注册表能够执行命令;对于打开命令,这在大多数情况下是:Bash "PROGRAM_TO_OPEN_THE_FILE_WITH'S_PATH\program.exe" "%L" "%*"。该命令将在每次打开与program.exe关联的文件时运行;%L是正在打开的文件的路径,%*是通过拖放处理程序获得的拖放文件的路径;这不会适用于WSL。

然而,可以利用这个系统:bash.exe和wsl.exe都可以被调用以静默执行bash脚本:对于前者,使用-c选项,对于后者,只需在之后写入命令即可。能做的是,因此,编写一个小型bash脚本,解析所有来自Windows路径到Unix路径的参数,然后运行实际的.sh脚本/Linux可执行文件。

# 获取所有文件路径,不进行扩展/替换 read -r -d '' path_param <<'EOF'%*EOFread -r -d '' path_exec <<'EOF'%LEOFpath_param=$(echo $path_param | tr -d '"' | sed 's/[[:space:]]\([A-Z]:\)/\n\1/g' | sed 's/[A-Z]:/\/mnt\/\L&/g' | tr '\\' '/'\'); mapfile -t path_param <<< "$path_param"; path_param=("${path_param[@]//:}"); path_exec=$(echo $path_exec | sed 's/[[:space:]]\([A-Z]:\)/\n\1/g' | sed 's/[A-Z]:/\/mnt\/\L&/g' | tr '\\' '/'\'); path_exec="${path_exec//:}"; cd "${path_exec%\/*}"; if [[ ${path_param[@]} == "" ]]; then "$path_exec"; else "$path_exec" "${path_param[@]/#${path_exec%\/*}\/}"; fi; cd ~; bash;

为了将所有这些代码放入一个Windows注册表键中,必须将所有的%字符替换为%%,并将所有的新行替换为;。除了在heredoc命令(初始读取命令)之间的新行字符,将使用换行字符,为了方便,将用大便表情符号(💩)来表示。

"%SYSTEMROOT%\System32\bash.exe" -c printf\ \ "💩read -r -d '' path_param <<'EOF'💩%*💩EOF💩read -r -d '' path_exec <<'EOF'💩%L💩EOF💩path_param=$(echo $path_param | tr -d '"' | sed 's/[[:space:]]\([A-Z]:\)/\n\1/g' | sed 's/[A-Z]:/\/mnt\/\L&/g' | tr '\\' '/'\'); mapfile -t path_param <<< "$path_param"; path_param=("${path_param[@]//:}"); path_exec=$(echo $path_exec | sed 's/[[:space:]]\([A-Z]:\)/\n\1/g' | sed 's/[A-Z]:/\/mnt\/\L&/g' | tr '\\' '/'\'); path_exec="${path_exec//:}"; cd "${path_exec%%\/*}"; if [[ ${path_param[@]} == "" ]]; then "$path_exec"; else "$path_exec" "${path_param[@]/#${path_exec%%\/*}\/}"; fi; cd ~; bash;
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485