Перетворити шлях Windows для Windows Ubuntu Bash


32

У мене є пакетний сценарій 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
войовнича Шимпанзе

1
posh потребує втечі '\', але wsl ні. ваш приклад $ 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, це не друкує два «\\»
Папо

1
Я вважаю, що wslpathце частина відповіді, але я вважаю, що ця публікація не функціонально відповідає на запитання - яке запитує, коли пакетний файл має C:\foo\bar\blahім'я файлу даних у стилі Windows ( ), як він виконує команду WSL цей файл?
Скотт

@papo Я щойно натрапив на проблему з нарізаною косою рискою: вона непослідовна і залежить від того, як вона запущена, коли запущена з powerhell, вона просто опускає нерозглянуті косої риски, а при запуску з bash - правильно їх розглядає лише всередині рядка.
sukhmel

@sukhmel true, у wsl (на якому працює баш для windows), а також у cmd-консолі, або кладіть шлях в одинарних або подвійних лапках, або біжіть як \\ Незбагливість уникнути внутрішніх лапок пропонує швидкий спосіб виконання: cat `wslpath 'тоді перетягніть і впустіть подайте в консоль і закінчіть рядок:'`
папо

5

Я написав файл 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

А як щодо зворотного, перетворення шляху 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'`

Використовуйте зворотні позначки перед wslpath та в кінці, а також використовуйте одинарні лапки (прямі кліщі) біля% 1.

Працює для мене.


Дійсно? Це вирішує проблему в питанні, куди bashвикликається з пакетного файлу? (Зверніть увагу, що у прикладі перший аргумент bash такий -lic, тому мені незрозуміло, як wslpath '%1'це буде працювати.) І чому ви змінилися з подвійних лапок ( "%1") на одиничні лапки ( '%1')?
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.