Windows cmd: невозможно экранировать процентную переменную с пробелами в имени файла?

Как мне правильно избежать такого пути к файлу в командной строке Windows? Тот, у которого в имени файла есть пробелы, проценты и переменные, такие как %cd% и %errorlevel%, без расширения переменных? Возможно ли это?

Например, запустите C:\Users\the impossible %cd% filepath.exe

Я искал и пробовал все вокруг для экранирования процентов и экранирования кавычек. Без переменных в имени файла это работает. Однако, если имя файла содержит проценты с такими переменными, как %cd% или %errorlevel%, ничего не работает вообще, независимо от какой-либо escape-последовательности.

Вещи, которые я пробовал:

"C:\Users\the impossible %cd% filepath.exe"

"C:\Users\the impossible %%cd%% filepath.exe"

"C:\Users\the impossible ^%cd^% filepath.exe"

Команды нет. Я просто пытаюсь запустить процесс в командной строке Windows. Я пытаюсь запустить исполняемый файл «C:\Users\the невозможный %cd% filepath.exe».

sahlaysta 23.08.2024 21:44

Пакетного файла нет, это просто команда. Я имею в виду запуск командной строки Windows и запуск исполняемого файла: «C:\Users\the невозможный %cd% filepath.exe»

sahlaysta 23.08.2024 21:53

Почему вы использовали тег [bat-file ], начали заголовок с «batch:», а вопрос начали с «In Batch»? Кроме того, почему вы не можете открыть приглашение PowerShell для его запуска?

Compo 23.08.2024 21:54

Исправлено, надеюсь, теперь мой вопрос стал яснее.

sahlaysta 23.08.2024 21:57

возможен дубликат . Если вам это не помогло, пожалуйста, уточните

Stephan 24.08.2024 08:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Итак, в вашем случае вы можете использовать:

^"C:\Users\the^ impossible^ %cd^%^ filepath.exe^"

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

Но знак каретки не может избежать знака процента %cd^% Парсер пытается найти переменную с именем cd^, если такой переменной нет, он просто удаляет курсор и текст остается нетронутым.
Каретки перед пробелами необходимы для сохранения целостности имени файла.

Но если такая переменная существует, команда завершится неудачно:

set "cd^=FAIL"

Существует второй вариант, в котором можно избежать одиночных знаков процента.

for /F "tokens=1-31" %%= in ("1") do "C:\Users\the impossible %%=cd%%= filepath.exe"

Одиночный знак процента экранируется путем преобразования его в %%=

Это работает, поскольку первый знак процента просто остается на месте, а %= расширяется до нуля.
На одной из фаз пакетного парсера синтаксический анализатор пытается расширить %=cd%, но переменная не может начинаться со знака равенства, поэтому это безвредно.
Этот вариант является пуленепробиваемым, никакая предопределенная переменная не может его нарушить.

Эту технику можно адаптировать так, чтобы для выхода из %= требовался только один %.

for /F "tokens=1-31 delims= = " %%= in ("1=2=3=4=5=6=7=8=9=0=1=2=3=4=5=6=7=8=9=0=1=2=3=4=%=6=7") do (
  echo "%=cd%=cd expands to '%cd%' special chars aren't a problem &<>|"
  "C:\Users\the impossible %=cd%= filepath.exe"
)

В окне командной строки в этом случае необходимо использовать:

^"C:\Users\the^ impossible^ ^%cd^%^ filepath.exe^"`

Вывод справки по запуску cmd /? в окне командной строки на последней странице справки объясняет, что имя файла (или любая другая строка аргумента) с пробелом или одним из этих символов &()[]{}^=;!'+,`~ (или буквально для интерпретации <>|, как в строке пароля/парольной фразы) должен быть заключен в ".

Все символы внутри строки аргумента, заключенной в ", интерпретируются буквально, включая символ ^, за исключением % (всегда) и ! при включенном расширении отложенной переменной, которое отключено по умолчанию в Windows.

% интерпретируется как начало/конец ссылки на переменную среды в командной строке, введенной в окне командной строки (или как ссылка на переменную цикла в случае цикла FOR). Но по сравнению с обработкой командной строки в пакетном файле что-то вроде %cd% заменяется перед выполнением командной строки чем-то другим только в том случае, если действительно существует динамическая переменная или переменная среды с таким именем. Что-то вроде %UnknownVariable% в строке имени файла не заменяется пустой строкой при выполнении командной строки, введенной в окне командной строки, при обработке командного файла %UnknownVariable% удаляется из командной строки перед выполнением, если нет переменной с именем UnknownVariable в настоящее время определено при обработке командной строки.

Причины разницы в обработке строк между двумя % между выполнением командной строки и выполнением пакетного файла просты:

  • Должна быть возможность ввести имя файла, содержащее один %, что не так уж необычно, как думают многие, или командную строку с несколькими %, например, для запуска исполняемого файла обработки изображений с такими параметрами, как width=75% height=50%. Такие параметры можно записать в пакетном файле как width=75%% height=50%%, т.е. е. знак процента для буквальной интерпретации экранируется знаком «больше процентов», чтобы не интерпретировать его как начало (или конец) переменной, цикла (внутри цикла FOR) или ссылку на строку аргумента пакетного файла.
  • Можно ожидать, что %Variable Name%, введенный пользователем в окне командной строки, предназначен для ссылки на существующую переменную. Если динамическая переменная или переменная среды с именем Variable Name отсутствует, пользователь либо допустил ошибку при вводе, либо %Variable Name% вообще не ссылается на переменную. Командный процессор Windows при обработке пакетного файла может ожидать, что создатель пакетного файла не допустил опечатки. Это также очень распространено в пакетных файлах, ссылающихся на переменные, которые в настоящее время не существуют при обработке командной строки перед ее выполнением. Подумайте о переменных, определенных с необязательными параметрами, которые не существуют, если параметры не используются, или о ссылке на переменную, где при первом выполнении командной строки переменная, на которую ссылаются, еще не существует, но существует позже при повторном выполнении той же командной строки.

Командный процессор Windows заменяет %Variable Name% всегда значением указанной переменной или пустой строкой, если нет переменной с именем %Variable Name% при обработке пакетного файла, но заменяет ссылку на переменную только в том случае, если переменная действительно существует при обработке командной строки, введенной в окно командной строки или передается cmd.exe после опции /C или опции /K при ее запуске.

Вывод справки по запуску set /? в окне командной строки также описывает наиболее часто используемые динамические переменные (не переменные среды). CD — одна из динамических переменных. Строка %cd% в имени файла, введенная в окне командной строки или прочитанная из пакетного файла, по этой причине всегда интерпретируется как ссылка на динамическую переменную CD.

В пакетном файле можно использовать:

"C:\Users\the impossible %%cd%% filepath.exe"

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

Следующая строка не может использоваться ни в окне командной строки, ни в пакетном файле, поскольку ^ внутри строки аргумента, заключенной в ", интерпретируется буквально, а не как escape-символ.

"C:\Users\the impossible ^%cd^% filepath.exe"

Решение не заключать строку аргумента в " специальным исключением из стандартных правил синтаксиса в этом случае использования, а вместо этого экранировать ^ каждым символом, например " и %, а также пробелом и использовать:

^"C:\Users\the^ impossible^ ^%cd^%^ filepath.exe^"`
  • ^" в начале указывает cmd.exe интерпретировать " буквально, а не как начало строки аргумента в двойных кавычках.

  • ^ слева от каждого символа пробела указывает cmd.exe интерпретировать пробел буквально, а не как разделитель строк аргументов.

  • ^% предписывает cmd.exe интерпретировать знак процента в этом случае буквально, а не как начало/конец ссылки на существующую переменную (или в цикле FOR как ссылку на переменную цикла).

  • ^" в конце указывает cmd.exe интерпретировать " буквально, а не как конец строки аргумента в двойных кавычках.

В результате строка имени файла с символами курсора интерпретируется как экранирующие символы с помощью cmd.exe как строки аргумента:

"C:\Users\the impossible %cd% filepath.exe"

Эта строка теперь передается в функцию библиотеки ядра Windows CreateProcess, при этом окружающие " требуются, поскольку CreateProcess анализирует эту строку командной строки, а также, чтобы выяснить, какой исполняемый файл запускать, а имя файла содержит пробелы и знаки процента для интерпретации также буквально CreateProcess как это делается для первой строки аргумента, заключенной в двойные кавычки.

Другие вопросы по теме