2

In a batch file, is there any way to get the raw arguments or command? For example, given the following batch file:

echo "%1"

And then running:

my-file.bat ^1.1

I would like it to output ^1.1, but ^ is a special character—escape character—so it is evaluated and %1 contains 1.1.

It is possible to fix this by escaping the caret when inputting the command (ex. my-file.bat ^^1.1), but this is not desired in my situation as I'm building a cross platform tool that also has a shell implementation (where providing ^1.1 works).

So I am wondering either:

  1. Is there a way to get the raw unevaluated argument text of "^1.1"?
  2. Or is there a way to get the raw command string or perhaps the last executed command text? I could then take this and do my own parsing.

Thanks!

David Sherret
  • 101,669
  • 28
  • 188
  • 178
  • How are you passing, and what exactly is, the content you're sending to the batch file, to be evaluated as `%1`? Also I doubt very much that you intention is to really `echo` it, so what are you doing with that input argument? – Compo Oct 05 '20 at 17:20
  • @Compo the `echo "%1"` is in the batch file as an example. It's calling it in cmd like `my-file.bat ^1.1`. I want to get `^1.1` with the caret in the batch file somehow, but `%1` contains `1.1` instead of `^1.1`. I realize that's because `^` is an escape character. – David Sherret Oct 05 '20 at 17:23
  • When you say you're calling it in cmd, does that mean you have a `cmd.exe` window open, with the directory of `my-file.bat` as your current directory, and you're physically typing `my-file.bat ^1.1` and pressing the `[ENTER]` key? Also I asked what you're intending to do with the input argument. I ask because you've just typed it, so should already know what you typed. You must be performing some other task with it! – Compo Oct 05 '20 at 17:30
  • @Compo `my-file.bat` is a file in the current directory of a `cmd.exe` window that contains the text `echo "%1"`. I am typing `my-file.bat ^1.1` and pressing enter. The output is `1.1`, but my desired output is `^1.1`. Yes, I've just reduced the problem to a very simple example for the sake of this question. I'd like the input of `^1.1` stored in a variable in batch somehow then I will do other stuff with it. – David Sherret Oct 05 '20 at 17:35
  • I don't want the simplified example, because nobody would do what you're doing there, in a real world batch script. You're clearly intending to use the argument for something other than `echo`, the best way to attack this would be as part of that, not by just sticking a non required `echo` in there and hoping to get an answer which fulfills the true aim of your script. – Compo Oct 05 '20 at 17:44
  • @Compo I'm sorry that I seem to not be explaining this well enough, but I think it's pretty clear. The `echo` example is to demonstrate that `%1` contains `1.1` and not `^1.1`. I want `^1.1` passed from the command line to a batch file. Once it's in the batch file, I am reading from a different file then doing some comparisons to find and output the appropriate record. I think that reading from a file then doing comparisons is irrelevant and would only complicate this question. – David Sherret Oct 05 '20 at 17:52
  • It doesn't contain `^1.1`, because the parser has already removed your caret in this line `my-file.bat ^1.1`. In order to protect it you'd need to use `my-file.bat "^1.1"`. However, once it's in your script, `echo` will also remove the leading caret if those doublequotes are removed, hence the reason I need a proper task for this argument, and not just some made up command which will not be used in your actual non simplified script. – Compo Oct 05 '20 at 17:56
  • @Compo no, echo doesn't do that. If it's properly escaped like `my-file.bat ^^1.1` so the `%1` contains `^1.1`, then it will output `^1.1`—I already explained that in my question. What I'm wondering is if it's possible to get the raw command or argument as it appears before parsing. – David Sherret Oct 05 '20 at 18:04
  • I'm quite capable of reading David! You said that you didn't desire to escape it because you wanted a cross platform tool! So the best way, given your lack of provided information, to perform the task, is to use: `my-file.bat "^1.1"`, then have this content only in `my-file.bat` Line `1`: `@Set "arg[0]=%~1"& SetLocal EnableDelayedExpansion`; Line `2`: `@Echo !arg[0]!& EndLocal& Pause`. – Compo Oct 05 '20 at 18:13
  • Yes, so quoting then using `%~1` works (ex. `echo "%~1"`), but what I'm looking for is a way to avoid quoting and get the value of `^1.1` in a variable from the command line so the user doesn't have to remember to add quotes. It may be impossible, but that's what I'm asking. I disagree that it's a lack of information. – David Sherret Oct 05 '20 at 18:38
  • I would suggest for all of them you use `"^1.1"`! Which of your cross platform instances, do not accept a doublequoted argument string? – Compo Oct 05 '20 at 19:36
  • @Compo yeah, I'm unfortunately just going to ask the user to try to remember to surround it in double quotes since this isn't possible. – David Sherret Oct 05 '20 at 20:11

1 Answers1

2

Short: You can't

Long: You can't fetch any combination, but many.

The caret is the most problematic character, because it escapes the next character and is removed BEFORE the arguments are build.
Therefore it's not possible to get the raw, original input.

But there exist some more or less bullet proof techniques.
Best solution in most cases: SO:How to receive even the strangest command line parameters?
Has some minor drawbacks Same but can also fetch CR and LF

But if you call the batch file by an external process, you could be able to use the cmdcmdline variable, this is the best solution, as the arguments can be accessed really easy.

Btw. Later in your ode, you probably get another problem.
When you try to call another batch or executable file with exactly the same arguments, you have to escape them before.
Even that part is not easy

jeb
  • 78,592
  • 17
  • 171
  • 225
  • Thanks! I was just doing some tests outside batch files using [kerne32.dll's GetCommandLine](http://www.pinvoke.net/default.aspx/kernel32/GetCommandLine.html) and it did not seem possible with that either. – David Sherret Oct 05 '20 at 19:47
  • Can you now understand @DavidSherret, why I was insistent in knowing what the intent of the script was, instead of just assuming the answer to `echo %1` would suffice. – Compo Oct 05 '20 at 20:03
  • @DavidSherret In this case Compo is right. It's a big difference how you call your batch, from the command line, per drag&drop or by another process. Each variant has different rules and partial solutions. cmd.exe is a really nasty beast – jeb Oct 05 '20 at 20:05
  • As I've said, it's someone entering the command manually on the command line in a cmd.exe process. Thanks Jeb for answering my question of whether it was possible to get the raw command line text as entered by the user in a batch file. @Compo I can, but it wasn't relevant to my question. – David Sherret Oct 05 '20 at 20:07