0

I have a .bat file that works properly:

set list=1 5 10 18 22 27
for %%p in (%list%) do @ping 192.168.0.%%p -w 10 -n 1 | findstr "Reply Request"

When I try to run it inline, combined with & or && in one line like this

set list=1 5 10 18 22 27 && for %%p in (%list%) do @ping 192.168.0.%%p -w 10 -n 1 | findstr "Reply Request"

I get an error saying:

%%p was unexpected at this time.

What am I doing wrong?

If the combined command is in the bat file it does work, but not if pasted in the command line.

The purpose of this is to have excel generate one line copy-paste command to be run in the command prompt, as creation the batch file is not allowed on the remote system.

SOLVED: Thank you Magoo and Stephan! The solution is to enclose array:

set "list=1 5 10 18 22 27" 

And to use %p instead if %%p:

for %p in (%list%) do @ping 192.168.0.%p -w 10 -n 1 | findstr "Reply Request"

So final result:

set "list=1 5 10 18 22 27" && for %p in (%list%) do @ping 192.168.0.%p -w 10 -n 1 | findstr "Reply Request"

does work :)

PS: Magoo suggested more streamlined solution:

for %p in (1 5 10 18 22 27) do @ping 192.168.0.%p -w 10 -n 1 | findstr "Reply Request"

Simple, single command :)

Eki
  • 75
  • 9
  • I am not happy that that will work. I believe that `list` will be set in the environment of the caller, and if you were to generate a different list, then the first attempt would run the old list and the second attempt would run the new. I'd advocate `for %p in (1 5 10 18 22 27) do @ping 192.168.0.%p -w 10 -n 1 | findstr "Reply Request"` since you have control of the generation of the code that will be executed. – Magoo Jun 19 '22 at 19:30

2 Answers2

1

The value of list is undefined when the line is parsed, so batch substitutes nothing (the "contents" of list) for %list% and the resolved result that is executed is

set list=1 5 10 18 22 27 && for %%p in () do @ping 192.168.0.%%p -w 10...

So, what's wrong with

for %p in (1 5 10 18 22 27) do @ping 192.168.0.%p -w 10...

Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal backslash, Space or " - build pathnames from the elements - counterintuitively, it is likely to make the process easier.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • ... and directly on command line, use `%p` instead of `%%p` (described in `for /?`). See [here](https://stackoverflow.com/questions/30282784/variables-are-not-behaving-as-expected/30284028#30284028) for how to make it work. – Stephan Jun 19 '22 at 18:59
  • If I try to double quote enclose the array, I still get the same thing: C:\Users\ekosl>set "list=1 5 10 18 22 27" && for %%p in (%list%) do @ping 192.168.0.%%p -w 10 -n 1 | findstr "Reply Request" %%p was unexpected at this time. – Eki Jun 19 '22 at 19:03
  • "list" is an array of numbers, not string – Eki Jun 19 '22 at 19:06
  • Thank you ! changing both %p actually worked ! – Eki Jun 19 '22 at 19:09
  • 2
    **ALL** variables in batch are strings. No exceptions. The comment about setting strings is confusing matters. In normal batch programming, errors can be generated by using the `set string=value` syntax, so `set "string=value"` is preferred. Since you can't `set` a variable and use its newly-assigned value in a single line, it's not really relevant here. The line you need to construct for execution is `for %p in (1 5 10 18 22 27) do @ping 192.168.0.%p -w 10...` - the remainder of the line is as you had it. Single `%` for the reason in Stephan's comment – Magoo Jun 19 '22 at 19:13
1

To use a variable defined in the same line (or code block), you need delayed expansion

Delayed expansion is disabled by default, so you need to start a new instance of cmd with delayed expansion enabled:

cmd /v:on /c "set "list=1 5 10 18 22 27" & for %p in (!list!) do @ping 192.168.0.%p -w 10 -n 1 | findstr "Reply Request""

(Although I'd prefer Magoo's solution)

Stephan
  • 53,940
  • 10
  • 58
  • 91