Convertire il percorso di Windows per Windows Ubuntu Bash


31

Ho uno script batch di Windows che utilizza Windows Ubuntu Bash. Riceve un percorso Windows completo come argomento e quindi passa quel percorso a un comando in Ubuntu Bash.

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

Ecco "%1"il percorso completo di Windows, come"C:\some path\file.avi"

Il comando dà l'errore:

C:some pathfile.avi: Protocol not found

Cosa posso fare per convertire questo percorso di Windows in un percorso come /mnt/c/some\ path/file.aviil Bash di Windows potrebbe effettivamente comprendere?


Quello che vi serve è di sostituire tutte le occorrenze di C:con /mnt/c(potenzialmente per le altre lettere di unità, anche), giusto?
Kleinfreund,

Risposte:


41

Windows Build 17046 [1] contiene una nuova wslpathutility in grado di tradurre percorsi da / a WSL / Windows. Questo era noto mancante funzionalità WSL. [2]

Esempio di utilizzo:

$ echo $0
/bin/bash

$ which wslpath
/bin/wslpath

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

Puoi chiamare wslpathda Powershell su Windows:

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

wslpath opzioni e parametri:

-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
Per Windows precedenti, disponibile qui: github.com/laurent22/wslpath
Warlike Chimpanzee

1
elegante deve sfuggire a "\", ma non lo sarà. il tuo esempio $ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'dovrebbe essere $ wslpath -a 'C:\aaa\bbb\ccc\foo.zip'Funziona quando è scappato, ma scappare inutilmente è fonte di confusione. Si potrebbe presumere che debba essere evaso. Inoltre, penso che il descrizione -m, ... with ‘/’ instead of ‘\\’dovrebbe avere un '\' (lo so che è copia-incollato) Se lo fate wslpath -w /mnt/c/Users, non stampa due '\\'
papo

1
Credo che wslpathsia parte della risposta, ma credo che questo post non risponda funzionalmente alla domanda - che chiede, quando un file batch ha un C:\foo\bar\blahnome di stile Windows ( ) per un file di dati, come esegue un comando WSL su quel file?
Scott,

@papo Mi sono appena imbattuto in un problema con le barre usapaped: è incoerente e dipende da come viene eseguito, quando viene eseguito da PowerShell omette semplicemente le barre senza escape, quando eseguito da bash le tratta correttamente solo all'interno di una stringa.
sukhmel,

@sukhmel true, in wsl (su cui gira bash per windows) e anche in console cmd, o metti il ​​percorso tra virgolette singole o doppie, o scappa come \\ L'insolenza di sfuggire alle virgolette all'interno offre un modo veloce di fare: cat `wslpath 'quindi trascina e rilascia un file nella console e finire la linea:'`
papo

5

Ho scritto un file bat per fare questo. Posiziona il file ovunque tu stia lavorando o aggiungilo al tuo percorso (o semplicemente mettilo sopra il tuo codice, che sarebbe più facile lavorare con). Ricordare di assegnare prima "variabile" al percorso del file (se si utilizza un file separato, provare a utilizzare i parametri).

Cosa fa il codice:

1) Ottieni la prima lettera del percorso, che è l'unità.

2) Rimuovere le prime due lettere.

3) Cambia le barre.

4) Questa è la parte difficile: poiché Linux fa distinzione tra maiuscole e minuscole, dobbiamo convertire le lettere maiuscole in minuscole. Fallo abbinando ciascuno (dimmi se c'è un modo migliore). Puoi anche rimuovere le lettere di unità non necessarie, poiché probabilmente non hai più di dieci unità.

5) Combina tutto per dare la stringa finale.

Il risultato:

Ingresso:

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

Output (con le virgolette):

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

Il codice è il seguente:

@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

Che dire del contrario, convertendo un percorso Unix in un percorso Windows in uno script shell?
JacobTheDev,

@JacobTheDev, ti occorrerebbero solo lievi modifiche;)
PulseJet


0

Perché così complicato?

Cambia la voce del registro

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

a partire dal

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

per

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

Usa i backtick prima di wslpath e alla fine e usa le virgolette singole (segni di spunta) intorno a% 1.

Per me va bene.


Veramente? Questo risolve il problema nella domanda, da dove bashviene chiamato da un file batch? (Nota che, nell'esempio, il primo argomento di bash è -lic, quindi non mi wslpath '%1'è chiaro come funzionerà.) E perché sei passato da virgolette doppie ( "%1") a virgolette singole ( '%1')?
Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.