Powershell or Batch to execute a command with user-input parameters and to save them in a text file for future defaults - powershell

I have a program I want to execute with a line like this:
gams.exe program.gms user-defined-variable1 user-defined-variable2 ..........
Currently I use a batch file which prompts the user for input strings which are the user-defined variables, for example:
code:
set /P scen_num="(What scenario number would you like to simulate?) "
output:
(What scenario number would you like to simulate?)
the user types: 1
I use this batch file very often and there are multiple parameters. I would like to write the most-recent parameters to a text file, so that the next time I run the batch (or Powershell) file, the previously-used setting will be there on the prompt:
(What scenario number would you like to simulate?) 1
So I can spam ENTER if I want to execute exactly the same thing as the previous time.
Ideally I want to be able to do this in batch, though Powershell is acceptable if batch cannot do this.
How do I output to / read from a text file?
How do I make the prompt already contain a specified value before I type anything?

Another solution would be making a config batch, to save variables and call to set. You could just add something like this after all the variables are set.
Program.bat
:[ First variable acts to wipe file with single `>` ]
echo set var1=%var1% > config.bat
echo set var2=%var2% >> config.bat
echo set var3=%var3% >> config.bat
:[ etc ]
This will create a batch like so:
config.bat
:[ setting variables to random data for examples sake.
set var1=Hello
set var2=I am
set var3=text.
You can add the option to either manually set your variables, or just
call config.bat
And if you wish to have multiple default settings, you can just add these as seperate batch scripts, by adjusting Program.bat to something like:
Program2.bat
echo set var1=%var1% > %name%.bat
echo set var2=%var2% >> %name%.bat
echo set var3=%var3% >> %name%.bat
Setting %name% to whatever you wish if you opt to save your settings into a batch, and then just replace
call config.bat
:[ with ]
call %name%.bat
You did mention the ability to just tap enter for a variable you wanted to set default, that could be done with something like:
:[ Have the variables saved in config.bat set to retrievable variables ]
call config.bat
set 1=%var1%
set 2=%var2%
set 3=%var3%
:[ Set the variables, if `enter` pressed set to retrievable variable ]
echo Enter var1
set /p var1=
if not defined var1 (
set var1=%1%
)
echo Enter var2
set /p var2=
if not defined var2 (
set var2=%2%
)
echo Enter var3
set /p var3=
if not defined var3 (
set var3=%3%
)

Related

Netlogo - Behavior Space

I want to run experiments using behavior space. However, the number of experiments needed is depending on the length of a list which is dynamic subject to the external data loaded. Hence , I want to do something like below which is not supported:
what is the correct way to do so? thanks
You note that you do this with a .bat or .sha file. If that's the case, here's a .bat solution. However, I'm not sure what your data looks like- in this example I just used the number of entries in a csv file to determine the number of runs needed.
So, I have a data file called 'example_data.csv' that looks like this:
1
100
1000
10000
I have an .nlogo file with an Input widget that defines a global variable called n_runs. I pulled out the xml for an BehaviorSpace experiment and saved it in a file called "experiment_base.xml"- it looks like:
<experiments>
<experiment name="experiment" repetitions="1" sequentialRunOrder="false" runMetricsEveryStep="false">
<setup>setup</setup>
<go>tick</go>
<timeLimit steps="5"/>
<metric>count turtles</metric>
<steppedValueSet variable="n_runs" first="1" step="1" last="1"/>
</experiment>
</experiments>
I have a .bat file that:
counts the number of entries in my 'example_data.csv"
reads in the 'experiment_base.xml' file and replaces the last="1" with the number read above, then writes this as a new experiment called 'mod_experiments.xml'
runs the experiment using the newly generated experiments file
This entire bat file looks like:
#echo off
cls
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" example_data.csv | find /C ":""
for /f %%a in ('!cmd!') do set number=%%a
powershell -Command "(gc experiment_base.xml) -replace '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"1\"/>', '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"%number%\"/>' | Set-Content mod_experiments.xml
echo "Running experiment..."
netlogo-headless.bat ^
--model dynamic_behaviorspace.nlogo ^
--setup-file mod_experiments.xml ^
--table table-output.csv
This outputs results for 4 experiments, since I had 4 values in my data file. If I modify the number of entries in the csv and rerun the .bat file, I get results for a corresponding number of runs.

Ask for user credentials in Batch file

I'm trying to figure out how to prompt the user for entering his user credentials and process the password inside a batch file.
After some fair amount of tinkering I came up with the following code:
#echo off
set password=
FOR /F "tokens=* USEBACKQ" %%F IN (`powershell -NoLogo -NoProfile -Command ^(Get-Credential "ag\%username%"^).GetNetworkCredential^(^).password;`) DO (
set password=%%F
)
echo %password%
This works fine if the user enters a non empty password. But if the user enters nothing or simply closes the dialog window by clicking "cancel", the variable "password" suddenly contains the string "ECHO ist ausgeschaltet (OFF)." instead of an empty string.
Does anyone have an idea how I can return an empty string for the password in this case?
Thanks in advance
solid
An environment variable has always a value. If an empty string is assigned then the variable is removed (in the running process).
SET FOO=
The variable FOO is removed with the statement above.
So you need to check if a variable is defined and not empty.
if defined FOO echo FOO:%FOO%
if not defined FOO echo FOO is not defined
In reality password is not defined.
That you got ECHO ist ausgeschaltet (OFF) is the output of the ECHO command, as you call it with no data.
To see the real content, you could use set password or ECHO(, the strange opening parenthesis prevents problems when the content of your variable is empty
...
echo( %password%
set password
Btw. You should use the extended set syntax, to avoid problems with trailing whitepsaces.
set "password="
...
set "password=%%F"

Can't make a directory using a variables value - Command Prompt

I'm trying to set up a simple backup process for a folder on my C drive that will back that folder up to another location on the network. I know how to create a scheduled task but I'm struggling to understand why my command prompt code won't work - I'm a novice when it comes to the Command Prompt though!
So my question is two fold:
Why does echo %variableName% not return the variable value - it only returns %variableName%.
This is what I type in:
#echo off
set varA = 5
echo %varA%
%varA% <- This is what its popping out
Do I need different preceeding and succeeding characters for this?
I want to create a folder with the date for the name (I do realize that are quite a few questions out there on this but they didn't work), how do I do it?
Here is what I tried:
set folder_name = %DATE:/=_%
set folder_name <- Display value for folder_name
folder_name = Wed 11_06_2013 <- Actual value
When I try to do this:
mkdir %folder_name%
dir
Creates a folder with this %_date% as the name.
Where am I going wrong?
Thanks
Space is significant in SET statements.
SET varspace=spacevalue
will set a variable named "varspace" to "spacevalue"
Remove the spaces and it should be plain sailing...
Oh - except that if the variable contains a space, then commands such as MD or mkdir (which are synonyms) require "rabbits ears" around the value, thus:
mkdir "%folder_name%"

Parse multiple arguments inside a batch file.

I would like to read two parameters that are passed to a batch file. The batch file will be executed from a C++ program using CreateProcess method. The second parameter to the batch file is a folder path, so from the program if I am passing the second parameter such as "E:\test folder\test2" the batch file does not get executed.
But if I instead pass E:\test folder\test2 the batch file gets executed but obviously the second parameter has the value E:\test only.. So what I would like to do is to read the first parameter using %1 and get the rest of the contents into another variable.
Can some one tell me how I can achieve this ? I tried with %* but it gives me both first and second parameters. I would like to remove the first token with space as delimiter so that I have the rest of the contents in the variable. Is there a way to do this ?
For example If I pass test.bat testparameter1 E:\test folder\test folder2\test folder3
I would like to read the value E:\test folder\test folder2\test folder3 into a variable.
If I pass test.bat testparameter1 E:\test\test folderX\test folderY the valueIi want to read in to a variable inside the batch file is E:\test\test folderX\test folderY
Can someone help me with this ? Thanks in advance.
Could you change spaces in the path by another character in your C++ code? For example, if we change spaces by arroba, then you could pass this:
test.bat testparameter1 E:\test#folder\test#folder2\test#folder3
and in the Batch file do the opposite change this way:
set param2=%2
set param2=%param2:#= %
Another possible method is to collect all the parameters from the second one on in the same variable, separating each one by one space:
set param1=%1
shift
set param2=
:nextParam
set param2=%param2% %1
shift
if not "%1" == "" goto nextParam
If your batch file is called with
test.bat testparam1 "E:\test\folder2\test folder 3"
You can read the parameters using %1 and %2
rem Contents of test.bat
#echo %0
#echo %1
#echo %2
The above produces:
C:\Temp>test testparam1 "E:\test\folder2\test folder 3"
test.bat
testparam1
"E:\test\folder2\test folder 3"
C:\Temp>
So you already have the parameters as variables; they're called %1 for the first one, %2 for the second, and so forth.
If the problem is that you're trying to do something using the "E:\test\folder2\test folder 3" path, just make sure you add a trailing backslash before passing it in:
"E:\test\folder2\test folder 3\"

How to create a user Environment variable that *calls* %date% or %time% each time it's invoked?

I'm trying to create 2 user environment variables with the following defintion:
datel=%date:~-4%%date:~3,2%%date:~0,2%
datetime=%date:~-4%%date:~3,2%%date:~0,2%-%time:~0,2%_%time:~3,2%_%time:~6,2%
so that every time I call:
echo %datel%
echo %datetime%
I get:
20110407
20110407-11_45_45
I can define the user environment variables without problems in the GUI (Computer->(Right Click)Properties->Advanced System Settings->Environment Variables) and when I do a "set" in a new cmd window I get the following:
>set da
datel=%date:~-4%%date:~3,2%%date:~0,2%
datetime=%date:~-4%%date:~3,2%%date:~0,2%-%time:~0,2%_%time:~3,2%_%time:~6,2%
But then "echoing" them is not what I expected:
C:\Users\jaravj
>echo %datel%
%date:~-4%%date:~3,2%%date:~0,2%
C:\Users\jaravj
>echo %datetime%
%date:~-4%%date:~3,2%%date:~0,2%-%time:~0,2%_%time:~3,2%_%time:~6,2%
Thanks a huge lot in advance.
Use call echo %datel% which results in another parsing pass (which you need here). echo by itself will not expand any environment variables, that does the shell upon parsing a line. Therefore you need to force that.
That's undocumented, however, so take that with a grain of salt. A more robust (i.e. actually supported) option might be to use a subroutine:
:expand
echo.%*
goto :eof
and then call it with
call :expand echo %datel%
Or use the delayed expansion, then you are able to expands two times in one line.
setlocal
set "datel=!date:~-4!!date:~3,2!!date:~0,2!"
setlocal EnableDelayedExpansion
echo %datel%
It's works because, first the batch line parser expands %datel% to !date:~-4!!date:~3,2!!date:~0,2! and after all percent expansions are done.
Then the escape characters are handled, and then as the last phase the parser expands the exclamations are expanded.
Explained in how cmd.exe parse scripts