为 Windows Ubuntu Bash 转换 Windows 路径

lag*_*lex 60 windows-subsystem-for-linux

我有一个使用 Windows Ubuntu Bash 的 Windows 批处理脚本。它接收一个完整的 Windows 路径作为参数,然后将该路径传递给 Ubuntu Bash 中的命令。

@echo off
bash -lic 'ffmpeg -i "%1" output.avi'
Run Code Online (Sandbox Code Playgroud)

"%1"是完整的 Windows 路径,例如"C:\some path\file.avi"

该命令给出了错误:

C:some pathfile.avi: Protocol not found
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能将此 Windows 路径转换为/mnt/c/some\ path/file.aviWindows Bash 真正理解的路径?

小智 84

Windows Build 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
Run Code Online (Sandbox Code Playgroud)

您可以wslpath从 Windows 上的 Powershell调用:

>>> wsl wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip
Run Code Online (Sandbox Code Playgroud)

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 ‘\\’
Run Code Online (Sandbox Code Playgroud)

  • 豪华需要转义 '\',但 wsl 不需要。你的例子 `$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'` 应该是 `$ wslpath -a 'C:\aaa\bbb\ccc\foo.zip'` 它有效当逃脱时,但无用的逃脱令人困惑。人们可以假设它必须被逃脱。另外,我认为关于 `-m`、`... 用 '/' 而不是 '\\'` 的描述应该有一个 '\'(我知道它是复制粘贴的)如果你做 `wslpath -w /mnt/ c/Users`,它不打印两个 '\\' (3认同)
  • 我相信 `wslpath` 是答案的*部分*,但我相信这篇文章并没有在功能上回答这个问题——当批处理文件具有 Windows 样式 (`C:\foo\bar\blah` ) 数据文件的名称,它如何在该文件上运行 WSL 命令? (3认同)
  • 我们如何从文件名不带双反斜杠的批处理文件中完成这项工作? (2认同)

pul*_*jet 6

我写了一个bat文件来做到这一点。只需将文件放在您正在工作的任何位置或将其添加到您的路径中(或将其放在您的代码上方,这样更易​​于使用)。请记住首先将“变量”分配给您的文件路径(如果您使用的是单独的文件,请尝试使用参数)。

代码的作用:

1)获取路径的第一个字母,即驱动器。

2) 去掉前两个字母。

3) 改变斜线。

4)这是一个棘手的部分:由于Linux区分大小写,我们需要将大写驱动器号转换为小写。通过匹配每个来做到这一点(告诉我是否有更好的方法)。您也可以删除不必要的驱动器号,因为您的驱动器可能不超过 10 个。

5)将所有内容组合起来得到最终字符串。

结果:

输入:

E:\myfiles\app1\data\file.csv
Run Code Online (Sandbox Code Playgroud)

输出(带引号):

"/mnt/e/myfiles/app1/data/file.csv"
Run Code Online (Sandbox Code Playgroud)

代码如下:

@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
Run Code Online (Sandbox Code Playgroud)


小智 5

为什么这么复杂?

更改注册表项

HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command
Run Code Online (Sandbox Code Playgroud)

C:\Windows\System32\wsl.exe "%1"
Run Code Online (Sandbox Code Playgroud)

C:\Windows\System32\wsl.exe `wslpath '%1'`
Run Code Online (Sandbox Code Playgroud)

在 wslpath 之前和末尾使用反引号,并在 %1 周围使用单引号(直引号)。

对我有用。