В Windows ситуация несколько неприятнее. По сути, все программы Win32 получают одну длинную строку командной строки - оболочка (обычно cmd.exe
) может сначала выполнить некоторую интерпретацию, удаляя, например, перенаправления <
и >
, но она не разбить его на границы слов для программы. Каждая программа должна делать это самостоятельно (если они хотят - некоторые программы не беспокоятся). В программах на C и C ++ подпрограммы, предоставляемые библиотеками времени выполнения, поставляемыми с цепочкой инструментов компилятора, обычно выполняют этот шаг синтаксического анализа перед вызовом main()
.
Проблема, как правило, , вы не знаете, как данная программа будет анализировать командную строку . Многие программы скомпилированы с некоторой версией MSVC ++, чьи причудливые правила синтаксического анализа описаны здесь , но многие другие скомпилированы с разными компиляторами, которые используют разные соглашения.
Это усугубляется тем фактом, что cmd.exe
имеет свои собственные причудливые правила синтаксического анализа. Символ каретки (^
) обрабатывается как escape-символ, который заключает в кавычки следующий символ, а текст внутри двойных кавычек обрабатывается как кавычка, если встречается список хитрых критериев (подробные сведения о кровопролитии см. cmd /?
). Если ваша команда содержит какие-то странные символы, для cmd.exe
очень легко понять, какие части текста «заключены в кавычки», а какие не должны синхронизироваться с вашей целевой программой, и все адские разрывы исчезнут.
Итак, самый безопасный подход к экранированию аргументов в Windows:
- Экранировать аргументы так, как этого требует логика синтаксического анализа командной строки вызываемой вами программы. (Надеюсь, вы знаете, что это за логика; если нет, попробуйте несколько примеров и догадайтесь.)
- Объедините экранированные аргументы с пробелами.
- Префикс каждый не алфавитно-цифровой символ результирующей строки с
^
.
- Добавлять любые перенаправления или другие хитрости оболочки (например, объединяя команды с
&&
).
- Запустите команду с
system()
или обратными галочками.