แปลงเส้นทาง Windows สำหรับ Windows Ubuntu Bash


31

ฉันมีสคริปต์แบตช์ของ windows ที่ใช้ Windows Ubuntu Bash ได้รับพา ธ 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

ฉันจะทำอย่างไรเพื่อให้เส้นทาง Windows นี้แปลงเป็นเส้นทาง/mnt/c/some\ path/file.aviที่ Windows Bash เข้าใจได้จริง


สิ่งที่คุณต้องการคือแทนที่สิ่งที่เกิดขึ้นทั้งหมดC:ด้วย/mnt/c(อาจเป็นตัวอักษรไดรฟ์อื่นด้วย) ใช่ไหม?
kleinfreund

คำตอบ:


41

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

คุณสามารถโทรwslpathจาก Powershell บน Windows:

>>> 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 ‘\\’

1
สำหรับ Windows รุ่นเก่ามีให้ที่นี่: github.com/laurent22/wslpath
Chimpanzee Warlike

1
หรูต้องหนี '\' แต่ไม่ได้ ตัวอย่างของคุณ$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'ควรเป็น$ wslpath -a 'C:\aaa\bbb\ccc\foo.zip'มันทำงานเมื่อหนีออกมา แต่การหนีที่ไร้ประโยชน์นั้นทำให้เกิดความสับสน หนึ่งอาจคิดว่ามันจะต้องหลบหนี นอกจากนี้ผมคิดว่าคำอธิบายบน-m, ... with ‘/’ instead of ‘\\’ควรจะมีหนึ่ง '\' (ฉันรู้ว่ามันคัดลอกวาง) ถ้าคุณทำwslpath -w /mnt/c/Usersมันไม่พิมพ์สอง '\\'
Papo

1
ฉันเชื่อว่าwslpathเป็นส่วนหนึ่งของคำตอบ แต่ฉันเชื่อว่าโพสต์นี้ไม่สามารถตอบคำถามได้ - ซึ่งถามเมื่อไฟล์แบตช์มีชื่อ Windows-style ( C:\foo\bar\blah) ชื่อสำหรับไฟล์ข้อมูลวิธีรันคำสั่ง WSL บน ไฟล์นั้น
สกอตต์

@po ฉันเพิ่งสะดุดกับปัญหา slash usecaped: มันไม่สอดคล้องกันและขึ้นอยู่กับว่ามันจะทำงานอย่างไรเมื่อเรียกใช้จาก PowerShell มันก็เพียงแค่ข้ามเครื่องหมายทับไม่หนีเมื่อเรียกใช้จากทุบตีปฏิบัติต่อพวกเขาอย่างถูกต้องเฉพาะภายในสตริง
sukhmel

@sukhmel จริงใน wsl (ที่ทุบตีสำหรับ windows ทำงาน) และในคอนโซล cmd ทั้งใส่เส้นทางในคำพูดเดียวหรือสองครั้งหรือหลบหนีเป็น \\ ความไม่แน่นอนของการหลบหนีภายในคำพูดเสนอวิธีที่รวดเร็วในการทำ: cat `wslpath 'จากนั้นลากและวาง ยื่นเข้าไปในคอนโซลและจบบรรทัด:'`
papo

5

ฉันเขียนไฟล์ bat เพื่อทำสิ่งนี้ เพียงวางไฟล์ทุกที่ที่คุณทำงานหรือเพิ่มลงในพา ธ ของคุณ (หรือวางไว้เหนือรหัสของคุณซึ่งจะทำงานได้ง่ายกว่า) อย่าลืมกำหนด "ตัวแปร" ให้กับเส้นทางไฟล์ของคุณก่อน (หากคุณใช้ไฟล์แยกต่างหากให้ลองใช้พารามิเตอร์)

รหัสทำอะไร:

1) รับตัวอักษรตัวแรกของเส้นทางซึ่งเป็นไดรฟ์

2) นำตัวอักษรสองตัวแรกออก

3) เปลี่ยนเครื่องหมายทับ

4) นี่คือส่วนที่ยุ่งยาก: เนื่องจากลีนุกซ์เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่เราจึงต้องแปลงอักษรชื่อตัวพิมพ์ใหญ่เป็นตัวพิมพ์เล็ก ทำได้โดยจับคู่กัน (บอกฉันว่ามีวิธีที่ดีกว่านี้) คุณสามารถลบอักษรระบุไดรฟ์ที่ไม่จำเป็นได้เช่นกันเนื่องจากคุณอาจมีไดรฟ์ไม่เกินสิบ

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

สิ่งที่เกี่ยวกับการย้อนกลับการแปลงเส้นทาง Unix ไปเป็นเส้นทาง Windows ในเชลล์สคริปต์
JacobTheDev

@JacobTheDev คุณจะต้องแก้ไขเพียงเล็กน้อยเท่านั้น;)
PulseJet

จริง ๆ แล้วคิดออกมาเมื่อเช้านี้! gist.github.com/JacobDB/e71e22c3663175b2369211aeb54362fe
JacobTheDev

0

ทำไมจึงซับซ้อน

เปลี่ยนรายการรีจิสทรี

HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command

จาก

C:\Windows\System32\wsl.exe "%1"

ถึง

C:\Windows\System32\wsl.exe `wslpath '%1'`

ใช้ backticks ก่อน wslpath และท้ายที่สุดและใช้เครื่องหมายอัญประกาศเดี่ยว (เห็บตรง) ประมาณ% 1

ได้ผลสำหรับฉัน


จริงๆ? วิธีนี้จะช่วยแก้ปัญหาในคำถามที่bashเรียกว่าจากไฟล์แบทช์? (โปรดทราบว่าในตัวอย่างอาร์กิวเมนต์แรกของ bash คือ-licดังนั้นจึงไม่ชัดเจนสำหรับฉันว่าwslpath '%1'จะทำงานอย่างไร) และทำไมคุณถึงเปลี่ยนจากเครื่องหมายคำพูดคู่ ( "%1") เป็นคำพูดเดี่ยว ( '%1')
สกอตต์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.