0

When I first started trying to build this, as a way of keeping an external file holding variables for IP addresses so I only ever had to edit one list, I felt I was doing something wrong. But then it worked. However it also outputted The system cannot find the drive specified in between the 'IP' and 'Name'. this stopped when I changed :: to rem, (code updated)

I aim to base a lot of automatic deployment and maintenance off of this, in calls to servers e.g. pscp/ plink (PuTTY) and in writing to log files to say e.g. Deploying on [name] xxxx. Is this a robust/appropriate way of writing this code? It feels strangely clean to me.

Can I check: is using the !xxx! making use of the delayed expansion? If so, should you always wrap variables in ! for delayed expansion? (I read Windows Batch files: what is variable expansion, and what does EnableDelayedExpansion mean? but it's not 100% clear to me that it's the ! which is causing this.)

What is this called? Am I using a variable value as the name of the variable and is there a computer science phrase for this? Is it an eval?

@echo off
setlocal EnableDelayedExpansion 

set ips[0]=192.168.0.1
set 192.168.0.1=router
set ips[1]=192.168.0.2
set 192.168.0.2=printer
set ips[2]=192.168.0.3
set 192.168.0.3=nas

for /F "tokens=2 delims==" %%a in ('set ips[') do (
    rem the next line outputs the IP as it is evaluating the dynamic 
    rem variable being temp created with the for loop
    echo IP is %%a
    rem with delayed expansion set (see top) we can use the value 
    rem of the IP that is being used with the for loop
    rem and further lookup by essentially evaluating again 
    echo Name of IP is !%%a!
)
pause

RESULT:

IP is 192.168.0.1
Name of IP is router
IP is 192.168.0.2
Name of IP is printer
IP is 192.168.0.3
Name of IP is nas
Press any key to continue . . .

Putting IP array into external file

So continuing with the edited code (edits reflected above), I now try to move the IP array into an external file and call it in, and it gives Environment variable ips[ not defined

demo.bat:

@echo off
setlocal EnableDelayedExpansion

call info_IPs.bat

for /F "tokens=2 delims==" %%a in ('set ips[') do (
    rem the next line outputs the IP as it is evaluating the dynamic 
    rem variable being temp created with the for loop
    echo IP is %%a
    rem with delayed expansion set (see top) we can use the value 
    rem of the IP that is being used with the for loop
    rem and further lookup by essentially evaluating again 
    echo Name of IP is !%%a!
)
pause

info_IPs.bat:

@echo off
setlocal EnableDelayedExpansion

set ips[0]=192.168.0.1
set 192.168.0.1=router
set ips[1]=192.168.0.2
set 192.168.0.2=printer
set ips[2]=192.168.0.3
set 192.168.0.3=nas
ja_him
  • 417
  • 1
  • 4
  • 20
  • 4
    Don't use `::` to place comments, specially inside code blocks. Use `rem` – MC ND Feb 27 '19 at 16:50
  • Changing `::` to `rem` has stopped the outputting of `The system cannot find the drive specified?` – ja_him Feb 27 '19 at 17:20
  • Did this solve your problem? Or you have another one, now? – double-beep Feb 27 '19 at 17:31
  • It makes *that* code work, but as I wrote in the post, the array is to be used like an "include" into other files, so I only have to edit the IPs in one file. And by removing the IPs into their own file (info_IPs.bat) and adding `call info_IPs.bat` I now get `Environment variable ips[ not defined` – ja_him Feb 27 '19 at 17:46
  • @Compo I find no reason for the rollback. Editing a question to: a) say that you have solved your problem posting the code you have used and the output you got (desired), b) include mentions, symbols, ping an answerer to say their answer did not work posting their code, etc. c) 'deface' the question to change the problem OP facing because they solved their previous problem **is not allowed**. He may post an answer to say the way he has solved the problem or delete their question and ask a new one. – double-beep Feb 27 '19 at 17:54
  • @double-beep, the originator of the question has made an edit to reflect the changes they were advised about in the comment area. That is absolutely the correct procedure, their question wasn't solved to their satisfaction, and you do not have the right to decide that yourself. Please be more careful weilding the power to be able to edit other peoples posts. – Compo Feb 27 '19 at 17:59
  • @double-beep It's only partially answered thus far. I theorise "as a way of keeping an external file holding variables for IP addresses so I only ever had to edit one list", is a key factor. All the remaining questions, if answered, should help users (and me) unpick the title. Hopefully people will understand the narrative this question is creating. [this comment](https://stackoverflow.com/questions/54910306/evaluate-an-evaluation-using-delayed-expansion-to-make-a-variable-value-usable-a#comment96589760_54910306) is key, really. – ja_him Feb 27 '19 at 18:32
  • 3
    You almost have it. As you are using `setlocal` in the called batch (`info_ips.bat`), any change you made to the environment inside this batch file **will be discarded** when the batch file ends as the `endlocal` is automatically executed. Just remove the `setlocal enabledelayedexpansion` at the start of the called file – MC ND Feb 27 '19 at 18:52
  • @MCND Yes! Thank you. Is there a term for the evaluating an evaluation (the title basically? And do the exclamation marks signify the use of delayed expansion? If you want to answer I'll glady accept. – ja_him Feb 27 '19 at 19:00
  • 1
    Want to make it clear that the only reason this works is because you are using delayed expansion. You would not be able to get the value of the variable using normal percent expansion because the variable name starts with a number. – Squashman Feb 27 '19 at 19:04
  • 2
    Personally I would do the set command like this: `set ips[0]=192.168.0.1=router`. Then change the `FOR` command to this. `for /F "tokens=2,3 delims==" %%a in ('set ips[') do`. Now %%a is the ip address and %%b is the name of the device. – Squashman Feb 27 '19 at 19:09
  • 2
    *If so, should you always wrap variables in ! for delayed expansion?* **No**. `Set !Cat!=Something` is a valid command without command extensions enabled as variables can contain `!`, however it will do something different if extensions are enabled. This is why they are not enabled by default. You have to opt in and give up variables with `!` in their names **OR** values. Also `Echo Warning! Shields are Down!` will work differently. – Noodles Feb 27 '19 at 21:03
  • Great tips, always worth doing the full learning, rather than just getting something working and leaving it. Thanks, +1s all round. – ja_him Feb 28 '19 at 08:20

0 Answers0