1

I have the following commands and a simple program that outputs received arguments. First command line printer.exe arg1 \" ^" arg2 is split into printer.exe, arg1, " and ^ arg2 and the second one printer.exe arg1 ^"arg2 which is split into printer.exe, arg1 and arg2. My question is, why in the second command the caret ^ is skipped?

Thanks!

tairqammar
  • 151
  • 3
  • 10
  • 2
    Well, this strongly depends on how `printer.exe` parses its arguments. Are you executing this in a Windows Command Prompt window (`cmd.exe`)? – aschipfl Mar 23 '20 at 02:29
  • Yes, `printer.exe` is executed in `cmd.exe` and arguments are parsed by CRT and I only print them. – tairqammar Mar 23 '20 at 08:04
  • 1
    For `cmd.exe` the `\ `does not mean any special, only the `^` is the escape character; quoting disables special character recognition and thus escaping; so reading from left to right, your first example results in `printer.exe arg1 \" ^" arg2` (unaltered), and your second example in `printer.exe arg1 "arg2` (you escaped the quote her); now it depends on `printer.exe` how it treats these command lines... – aschipfl Mar 23 '20 at 11:04

1 Answers1

2

There are many problems for program arguments.

To understand them, you need to know how the line is parsed.

First the line is parsed by cmd.exe.
There are many rules (and phases), but in your case there are only two relevants.

  1. Each quote toggle the quoted-mode, in the quoted-mode, special characters lose their special meaning

  2. A caret escapes the next character, the caret itself will be removed.
    The caret can also escape a quote, to avoid the activation of the quoted-mode.
    This only works in unquoted mode, inside quotes the caret loses its special meaning.

Backslashes have no special meaning for cmd.exe.

For your examples, cmd.exe will parse them to:

printer.exe arg1 \" ^" arg2
-> printer.exe arg1 \" ^" arg2     --- The caret is inside quotes

printer.exe arg1 ^"arg2
-> printer.exe arg1 "arg2          --- The caret was outside quotes

On windows each program.exe is responsible for splitting the command line into arguments, despite to a linux, where the shell decides how to split the arguments.

The consequence for windows programs is:
A total mess!

You need to know the rules of every program, to know how the line is splitted into arguments.
There are programs that have rules with support of backslashes or double double-quotes, some with single quotes and some without the ability to build arbitrary arguments.

For some more explanations How does the Windows Command Interpreter (CMD.EXE) parse scripts?

jeb
  • 78,592
  • 17
  • 171
  • 225
  • In the first case, the caret that should toggle the `quoted-mode` is escaped by `\`, so why the caret is considered to be inside quotes? – tairqammar Mar 23 '20 at 08:42
  • 2
    @tairqammar In the first case the first quote (the one with the backslash) activates the quoted-mode, therefore the caret loses any special meaning and the second quote disables the quoted-mode again – jeb Mar 23 '20 at 10:10
  • 2
    The backslash doesn't escape anything within the `cmd` parser (which processes the line before forwarding it to the application). It's "just an ordinary character" (but the application can treat it differently) – Stephan Mar 23 '20 at 10:40