Передача filepath с пробелами или без них в cygwin внутри пакетного скрипта .. "'\ confusion - PullRequest
0 голосов
/ 04 ноября 2018

После нескольких часов и бесчисленного количества попыток ставить «там» и «где» я мог себе представить и пытаясь найти ресурс о том, как именно то, что я пытаюсь сделать, обрабатывается, я теряюсь в большей растерянности, чем до того, как я начал пытается .. К сожалению, я очень незнаком с пакетными сценариями в Windows.

Я пытаюсь написать пакетный скрипт, который принимает windows filepath в качестве аргумента, который может содержать пробелы или нет. Затем этот путь к файлу должен быть передан команде внутри cygwin, а выход, который является просто измененным путем к файлу (все еще windows путь к файлу), должен быть затем назначен переменной в пакетном сценарии.

Я заставил его работать полностью, если путь к файлу не имеет пробелов ... но я не могу понять, как это сделать с пробелами. Я вижу, как магически появляются, иногда исчезают, иногда нет ... Самое дальнее, что я мог получить, это:

@echo off
set "a=%1"
for /f "delims=" %%i in ('C:\cygwin64\bin\bash --login -c "echo '%a%'"') do set "newpath=%%i"
echo %newpath%
pause

Это работает только для пути к файлу без пробелов (обратите внимание на%%%). Для пути с пробелами я получаю синтаксическую ошибку, такую ​​как

-c: line 0: unexpected EOF while searching for `''
-c: line 1: syntax error: unexpected EOF

(перевод, так как моя система не на английском языке). Если я удаляю около% a%, все \ s в пути к файлу исчезают (как и следовало ожидать от cygwin echo), а разделенные пути к файлам обрезаются после первого пробела. Если я заменим 's вместо' s, как это

@echo off
set "a=%1"
for /f "delims=" %%i in ('C:\cygwin64\bin\bash --login -c "echo "%a%""') do set "newpath=%%i"
echo %newpath%
pause

тогда он работает только для путей с пробелами, но не для путей без (все \ s исчезают). На данный момент я очень смущен тем, что происходит.

Очевидно, что я хочу передать буквальное «windows \ file \ path», включая одинарные кавычки, в cygwin, так как тогда все, что внутри, обрабатывается как литерал. Согласно некоторым источникам в сети, «в пакетном режиме» не имеет особого значения, кроме как в этом особенном для / f, как я его написал. Однако даже если я удалю присваивание for / f и присваивание переменной и попытаюсь вместо этого напрямую отобразить эхо, я также получу похожее странное поведение, которое не поможет мне ничего понять.

Может кто-нибудь помочь, как мне добиться того, что я пытаюсь сделать (написано курсивом выше)?


Редактировать

Провел дополнительное тестирование, и теперь мне кажется, что я понимаю поведение, но я все еще не знаю, как добиться того, чего я хочу.

Итак, в пакетном скрипте, если я передаю путь без пробела, переменная содержит

C:\some\path\without\space

но если я пройду путь с пробелом , переменная содержит

"C:\some\path with space"

т.е.. во втором случае они содержатся в переменной. Так что, если я передам первое в cygwin echo, я получу

echo C:\some\path\without\space

который выдаст

C:somepathwithoutspace

как и ожидалось. Если я прохожу вторую версию

echo "C:\some\path with space"

вывод

C:\some\path with space

снова, как и ожидалось. Аналогично, если я добавлю «s» к переменной в пакетном скрипте, cygwin echo просто пропустит и эти дополнительные «s», что приведет к измененному поведению, непустой путь будет выведен правильно, а путь с пробелами завершится ошибкой, потому что "" это просто пустая строка в bash.

Имхо, это поведение чрезвычайно .. глупо. Чтобы добиться того, чего я хочу, мне нужно как-то определить, цитируется ли уже содержимое переменной или нет, и добавить кавычки, если необходимо.


Вероятно, не важно , но, чтобы ответить на вопрос из комментариев, я хочу, конечно, не просто использовать echo, а различные сценарии bash, которые что-то делают с путем, который я прошел к нему. В конце концов, мне нужна программа, которую я могу быстро запустить в windows /, возможно, добавлю в мое контекстное меню, поэтому выполнение всего в cygwin bash лишает цели быстрое использование финальной программы, или, по крайней мере, я не знаю, как к. Причина, по которой я не делаю все в пакетном скрипте, заключается в том, что я вообще не знаю пакетного скриптинга, я просто использую минимум, необходимый для создания быстро доступной программы; пока делаю суть в bash, так как знаю как.

например. У меня есть файл .zip, где-то, который я хочу распаковать, посчитать файлы, выполнить некоторые команды linux для файлов (например, конвертировать), проанализировать имена файлов, изменить имена файлов и, в конце концов, запустить другую программу Windows для измененных файлов. , Промежуточные шаги уже требуют некоторых инструментов Linux; плюс вся обработка файлов, я понятия не имею, как это сделать в пакетном режиме, но очень легко в bash.

Моя единственная проблема - это вопрос, так как я хочу запустить финальную программу в любом каталоге, в котором находится архив, для которого я хочу использовать программу, т. Е. В пути к файлу может или не может быть пробелов.

1 Ответ

0 голосов
/ 05 ноября 2018

Оказывается, все, что мне нужно, это прочитать переданный путь к файлу вот так

@echo off
set "path=%~1"
for /f "delims=" %%i in ('C\cygwin64\bin\bash --login -c "./some/script.sh ""%path%"""') do set "outvar=%%i"
:: do more things ..

где я использовал

%~1

вместо

%1

чтобы прочитать мой аргумент filepath. Это предотвращает любые внутри содержимого переменной, поэтому я всегда могу добавить буквальные кавычки при передаче его в Cygwin, экранируя двойные кавычки с помощью

""
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...