我有一个使用 Windows Ubuntu Bash 的 Windows 批处理脚本。它接收完整的 Windows 路径作为参数,然后将该路径传递给 Ubuntu Bash 中的命令。
@echo off
bash -lic 'ffmpeg -i "%1" output.avi'
这"%1"
是完整的 Windows 路径,例如"C:\some path\file.avi"
该命令给出错误:
C:some pathfile.avi: Protocol not found
/mnt/c/some\ path/file.avi
我该怎么做才能让这个 Windows 路径转换为Windows Bash 真正能够理解的路径?
答案1
Windows 内部版本 17046[1]包含wslpath
可转换 WSL/Windows 路径的新实用程序。这是已知的 WSL 缺失功能。[2]
使用示例:
$ echo $0
/bin/bash
$ which wslpath
/bin/wslpath
$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip
您可以wslpath
从 Windows 上的 Powershell 调用:
>>> wsl wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip
wslpath
选项和参数:
-a force result to absolute path format
-u translate from a Windows path to a WSL path (default)
-w translate from a WSL path to a Windows path
-m translate from a WSL path to a Windows path, with ‘/’ instead of ‘\\’
答案2
我编写了一个 bat 文件来执行此操作。只需将文件放在您正在工作的地方或将其添加到您的路径中(或者将其放在您的代码上方,这将更容易使用)。请记住先将“变量”分配给您的文件路径(如果您使用的是单独的文件,请尝试使用参数)。
代码的作用:
1)获取路径的首字母,即驱动器。
2)删除前两个字母。
3) 更改斜线。
4) 这是比较棘手的部分:由于 Linux 区分大小写,我们需要将大写驱动器号转换为小写。通过匹配每个驱动器号来完成此操作(告诉我是否有更好的方法)。您也可以删除不必要的驱动器号,因为您的驱动器号可能不超过十个。
5)将所有内容组合起来,得到最终的字符串。
结果:
输入:
E:\myfiles\app1\data\file.csv
输出(带引号):
"/mnt/e/myfiles/app1/data/file.csv"
代码如下:
@echo OFF
set "variable=E:\myfiles\app1\data\file.csv"
set "drive=%variable:~0,1%"
set variable=%variable:~2%
set "variable=%variable:\=/%"
if %drive%==A set "drive=a"
if %drive%==B set "drive=b"
if %drive%==C set "drive=c"
if %drive%==D set "drive=d"
if %drive%==E set "drive=e"
if %drive%==F set "drive=f"
if %drive%==G set "drive=g"
if %drive%==H set "drive=h"
if %drive%==I set "drive=i"
if %drive%==J set "drive=j"
if %drive%==K set "drive=k"
if %drive%==L set "drive=l"
if %drive%==M set "drive=m"
if %drive%==N set "drive=n"
if %drive%==O set "drive=o"
if %drive%==P set "drive=p"
if %drive%==Q set "drive=q"
if %drive%==R set "drive=r"
if %drive%==S set "drive=s"
if %drive%==T set "drive=t"
if %drive%==U set "drive=u"
if %drive%==V set "drive=v"
if %drive%==W set "drive=w"
if %drive%==X set "drive=x"
if %drive%==Y set "drive=y"
if %drive%==Z set "drive=z"
set "variable=/mnt/%drive%%variable%"
echo "%variable%"
@echo ON
答案3
为何这么复杂?
更改注册表项
HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command
从
C:\Windows\System32\wsl.exe "%1"
到
C:\Windows\System32\wsl.exe `wslpath '%1'`
在 wslpath 之前和末尾使用反引号,并在 %1 周围使用单引号(直引号)。
对我有用。
答案4
这是我的 cdwin 脚本,将 win 目录更改为 wsl 路径
#!/bin/bash
line=$(sed -e 's~\\~/~g' -e "s/\([CD]\):/\L\1/" -e "s/^/\/mnt\//g" <<< "$1")
cd $line
使用:
#:cdwin 'C:\Users\win\Documents'
#:/mnt/c/Users/win/Documents$