2016-04-05 5 views
3

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

hello " world 

Это единственный аргумент. Вот мой пакетный файл:

@echo off 
@echo %1 

Теперь, если я запустить его из командной строки, я получаю следующие результаты:

>C:\file.bat "hello "" world" 
"hello "" world" 

>C:\file.bat "hello \" world" 
"hello \" 

>C:\file.bat "hello """ world" 
"hello """ 

Во всех случаях я получаю неправильный результат, как Я избегаю двойной цитаты и передаю ее правильно? Или я должен делать какие-либо дополнительные шаги преобразования в файле пакета?

+3

Вы можете попробовать прохождение '^"' .Карет - это escape-символ в консоли batch/cmd. – rojo

+0

'\' не является escape-символом в консоли Windows, как вы думали –

ответ

4

невозможно передать строку буквального значение hello " world, как параметр партии по двум причинам:

  1. Пространство не может быть экранировано относительно токенизации параметра. Параметры всегда разделяются символами без кавычек, даже если им предшествует escape-символ ^. Знаки маркеров токенов-параметров: {space}, {tab}, ,, ;= и {0xFF}. Единственный способ включить разделитель токенов как часть параметра - убедиться, что разделитель указан.

  2. Невозможно избежать цитаты в указанной строке. Котировки - это конечный автомат: первая встречаемая цитата включает семантику цитаты, а последующая ее отключает. Следующая цитата снова включает его и т. Д. Если цитирование отключено, то листинг цитирования может быть экранирован как ^", чтобы сохранить цитирование. Но как только цитирование началось, тогда нет возможности избежать закрытия цитаты : Следующая цитата всегда отключается.

Поэтому независимо от того, как вы добавляете кавычки и/или спасшиеся кавычки, будет всегда быть в кавычках пространства, таким образом, строка будет рассматриваться как два параметра.

Вы можете принять strategy recommended by Hapax - Процитировать всю строку и удвоить любые литералы цитирования в строке: "Hello "" world".

Однако я бы сделал небольшое изменение и использовал %~1 вместо %1, чтобы удалить внешние кавычки.Затем удвоенные кавычки должны быть преобразованы обратно в одной цитате:

@echo off 
set "arg1=%~1" 
set "arg1=%arg1:"=%" 
echo %arg1% 

Но есть и другие потенциальные проблемы с передачи строковых литералов в качестве параметров партий. Самым коварным является удвоение каретки. Невозможно передать кавычку в качестве параметра, если вызывающий использует CALL. Я не пойду в механизм проблемы. См. https://stackoverflow.com/a/4095133/1012053, если вы хотите получить дополнительную информацию. Но следующее иллюстрирует проблему:

test.bat

@echo %1 

- Пример CMD сессии -

D:\test>test "^" 
"^" 

D:\test>call test "^" 
"^^" 

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

test2.bat

@echo off 
setlocal enableDelayedExpansion 
set "arg1=!%1!" 
echo !arg1! 

- Пример CMD сессии -

D:\test>set "myVar=Hello world! ^&|<>" How are you doing? !^^^&^|^<^>^" 

D:\test>set myVar 
myVar=Hello world! ^&|<>" How are you doing? !^&|<> 

D:\test>test2 myVar 
Hello world! ^&|<>" How are you doing? !^&|<> 

D:\test>call test2 myVar 
Hello world! ^&|<>" How are you doing? !^&|<> 
1

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

Выполнение использованием file.bat "hello "" world", мы используем:

@echo off 
set param=%1 
set param=%param:""="% 
echo %param% 

(результат: "hello " world")

Более короткая версия:

@echo off 
set param=%1 
echo %param:""="% 
+0

Означает ли это, что мне нужно вручную соединить nvert любая escape-последовательность в исходную форму, когда я передаю что-то в пакетный файл? – username

+0

Лорд, мы все еще пытаемся понять, какие обстоятельства сделали бы желательным, чтобы обозначить один символ кавычки как аргумент сценария. @username, я уверен, что применение любого совета, предлагаемого на этой странице, будет полностью вашим усмотрением, так как только вы понимаете безумие своих планов. Все это кажется мне [XY проблемой] (http://xyproblem.info/). – rojo

+0

@rojo моя проблема X заключается в том, чтобы исправить часть устаревшего программного обеспечения, которое уже делает это. Я не могу спросить Х, пока не пойму, что Y плох. Я думал, что это возможно как-то обойти, но кажется, что вся идея передачи параметров пакетным файлам проблематична. – username

Смежные вопросы