Konversi jalur Windows untuk Windows Ubuntu Bash

31

Saya memiliki skrip batch Windows yang menggunakan Windows Ubuntu Bash. Itu menerima path Windows penuh sebagai argumen dan kemudian melewati path itu ke perintah di Ubuntu Bash.

@echo off
bash -lic 'ffmpeg -i "%1" output.avi'

Berikut "%1"adalah jalur Windows lengkap, seperti"C:\some path\file.avi"

Perintah memberikan kesalahan:

C:some pathfile.avi: Protocol not found

Apa yang bisa saya lakukan untuk mengubah jalur Windows ini menjadi jalur /mnt/c/some\ path/file.aviyang benar-benar dimengerti oleh Windows Bash?

laggingreflex
sumber
Yang Anda butuhkan adalah mengganti semua kejadian C:dengan /mnt/c(berpotensi untuk huruf drive lain juga), kan?
kleinfreund

Jawaban:

41

Windows Build 17046 [1] berisi wslpathutilitas baru yang dapat menerjemahkan jalur dari / ke WSL / Windows. Ini dikenal sebagai fitur WSL yang hilang. [2]

Contoh penggunaan:

$ echo $0
/bin/bash

$ which wslpath
/bin/wslpath

$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

Anda dapat menelepon wslpathdari Powershell di Windows:

>>> wsl wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

wslpath opsi dan parameter:

-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 ‘\\’
tidak masuk akal
sumber
1
Untuk Windows yang lebih lama, tersedia di sini: github.com/laurent22/wslpath
Chimpanzee
1
mewah perlu melarikan diri '\', tetapi tidak. teladan Anda $ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'seharusnya $ wslpath -a 'C:\aaa\bbb\ccc\foo.zip'bekerja ketika melarikan diri, tetapi melarikan diri yang tidak berguna membingungkan. Orang bisa berasumsi itu harus diloloskan. Juga, saya pikir deskripsi pada -m, ... with ‘/’ instead of ‘\\’harus memiliki satu '\' (Saya tahu itu disalin) Jika Anda melakukannya wslpath -w /mnt/c/Users, itu tidak mencetak dua '\\'
papo
1
Saya percaya itu wslpathadalah bagian dari jawaban, tapi saya percaya bahwa posting ini tidak secara fungsional menjawab pertanyaan - yang menanyakan, ketika file batch memiliki nama Windows-style ( C:\foo\bar\blah) untuk file data, bagaimana cara menjalankan perintah WSL pada file itu?
Scott
@ papo Saya baru saja menemukan masalah dengan garis miring usecaped: tidak konsisten dan tergantung pada bagaimana dijalankan, ketika dijalankan dari PowerShell itu hanya menghilangkan garis miring yang tidak terhapus, ketika dijalankan dari bash ia memperlakukan mereka dengan benar hanya di dalam sebuah string.
sukhmel
@sukhmel true, di wsl (di mana bash untuk windows berjalan) dan juga di cmd console, baik letakkan path dalam tanda kutip tunggal atau ganda, atau melarikan diri sebagai \\ Ketidakberadaan melarikan diri dalam kutipan menawarkan cara cepat untuk melakukan: cat `wslpath 'kemudian seret & lepas a file ke konsol dan menyelesaikan garis:'`
papo
5

Saya menulis file kelelawar untuk melakukan ini. Cukup tempatkan file di mana pun Anda bekerja atau tambahkan ke jalur Anda (atau cukup letakkan di atas kode Anda, yang akan lebih mudah untuk dikerjakan). Ingat untuk menetapkan "variabel" ke jalur file Anda terlebih dahulu (jika Anda menggunakan file terpisah, coba gunakan parameter).

Apa yang dilakukan kode:

1) Dapatkan huruf pertama dari path, yang merupakan drive.

2) Hapus dua huruf pertama.

3) Ubah garis miring.

4) Ini bagian yang sulit: karena Linux peka terhadap huruf besar-kecil, kita perlu mengubah huruf drive huruf besar menjadi huruf kecil. Lakukan ini dengan mencocokkan masing-masing (beri tahu saya jika ada cara yang lebih baik). Anda juga dapat menghapus huruf drive yang tidak perlu, karena Anda mungkin tidak memiliki lebih dari sepuluh drive.

5) Gabungkan semuanya untuk memberikan string terakhir.

Hasil:

Memasukkan:

E:\myfiles\app1\data\file.csv

Output (dengan tanda kutip):

"/mnt/e/myfiles/app1/data/file.csv"

Kode tersebut adalah sebagai berikut:

@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
PulseJet
sumber
Bagaimana dengan sebaliknya, mengubah jalur Unix ke jalur Windows di skrip shell?
JacobTheDev
@ JacobTheDev, Anda hanya perlu sedikit modifikasi untuk itu;)
PulseJet
benar-benar menemukan jawabannya pagi ini! gist.github.com/JacobDB/e71e22c3663175b2369211aeb54362fe
JacobTheDev
0

Kenapa begitu rumit?

Ubah entri registri

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

dari

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

untuk

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

Gunakan backtick sebelum wslpath dan di akhir, dan gunakan tanda kutip tunggal (kutu lurus) sekitar% 1.

Bekerja untukku.

Stefan Oskamp
sumber
Betulkah? Ini memecahkan masalah dalam pertanyaan, di mana bashdipanggil dari file batch? (Perhatikan bahwa, dalam contoh, argumen pertama bash adalah -lic, jadi tidak jelas bagi saya bagaimana cara wslpath '%1'kerjanya.) Dan mengapa Anda mengubah dari tanda kutip ganda ( "%1") menjadi tanda kutip tunggal ( '%1')?
Scott