So, as the title says i would like to remove the directory or path that gets put in front of called commands if i output a batch file into a text file.
For example i've got a batch file like that
call :sub>log.txt
:sub
SET ip=127.0.0.1
ping %ip%
What i get as output is this:
C:\Users\...>SET ip=127.0.0.1
C:\Users...>ping 127.0.0.1
pingoutput
What i want is this:
SET ip=127.0.0.1
ping 127.0.0.1
pingoutput
The path in front can get pretty annoying for deep directories.
The examples above are just this, examples. I want to create a batch file to install a sql database and different triggers and functions with the batch file, so i can easily deploy it on different pcs.
Edit says: #echo off at the beginning just completely removes a line, even the command itself.
If deep paths is your real issue, there's a simpler fix, you probably haven't thought of. Change the prompt string.
#Prompt $G
Call :Sub 1> "log.txt"
#Prompt
GoTo :EOF
:Sub
Set "IP=127.0.0.1"
%__APPDIR__%ping.exe %IP%
In the case above, I have changed the prompt string to just a greater than character, after calling the label, using Prompt without an argument returns it to its default again. Also as you can see, the # character prefix turns off echoing for those commands, so they aren't shown in your console or output file.
In the example above I used $G because it still differentiates commands from output, but you could obviously play around with it to find something you prefer.
To find out more about the options available, open a Command Prompt window, type prompt /?, press the ENTER key, and read the information presented.
#echo off disables command echoing. That is kind off the point. if you want to see the command, then echo each command while #echo off is enabled:
#echo off
call :sub>log.txt
goto :eof
:sub
echo set ip=127.0.0.1 & SET ip=127.0.0.1
echo ping %ip% & ping %ip%
or if you do not want to use the `& operator, just newlines will work:
#echo off
call :sub>log.txt
goto :eof
:sub
echo set ip=127.0.0.1
SET ip=127.0.0.1
echo ping %ip%
ping %ip%
and completely without the calling of the label:
#echo off
(echo set ip=127.0.0.1 & set ip=127.0.0.1
echo ping %ip% & ping %ip%)>log.txt
Related
Could you please guide me how to fix my script to get the trace route results to some IP addresses?
I want to get the tracert results for 8.8.8.8 and 8.8.4.4. I wrote the script below and it works fine:
#echo off
echo %date% %time%
SET DNS1=8.8.8.8
SET DNS2=8.8.4.4
for %%i in (%DNS1% %DNS2%) do (
echo ----------------
echo tracert to %%i
tracert -d %%i
)
echo %time%
exit
I want to add a function so that it can print host name automatically. I tried as below, but it doesn't work.
#echo off
echo %date% %time%
SET DNS1=8.8.8.8
SET DNS2=8.8.4.4
for %%i in (%DNS1% %DNS2%) do (
echo ----------------
if (%%i == 8.8.8.8 set host=Google1
%%i == 8.8.4.4 set host=Google2)
echo tracert to %host%
tracert -d %%i
)
echo %time%
exit
Could somebody please correct the code for me?
The proper use to test multiple conditions using an IF command is used in this code. As a best practice I always use quotes around string comparisons. Also note the use of delayed expansion with the host variable. This is required because you are creating a variable inside a parenthesized code block.
#echo off
setlocal enabledelayedexpansion
echo %date% %time%
SET DNS1=8.8.8.8
SET DNS2=8.8.4.4
for %%i in (%DNS1% %DNS2%) do (
echo ----------------
if "%%i"=="8.8.8.8" set host=Google1
if "%%i"=="8.8.4.4" set host=Google2
echo tracert to !host!
tracert -d %%i
)
echo %time%
endlocal
exit
The batch file could be written like this:
#echo off
echo %DATE% %TIME%
setlocal EnableExtensions EnableDelayedExpansion
set "DNS1=8.8.8.8"
set "DNS2=8.8.4.4"
for %%i in (%DNS1% %DNS2%) do (
echo ----------------
if %%i == 8.8.8.8 set "host=Google1"
if %%i == 8.8.4.4 set "host=Google2"
echo tracert to !host!
tracert -d %%i
)
endlocal
echo %TIME%
exit /B
Windows command processor executes one command line after the other. How a command line is parsed before execution is described at How does the Windows Command Interpreter (CMD.EXE) parse scripts? What is executed finally after parsing a command line can be seen on executing a batch file without #echo off from within a command prompt window as described at debugging a batch file.
A command block starting with ( and ending with matching ) is parsed completely by cmd.exe before the command is executed with makes conditionally or unconditionally use of the command block. During parsing the command block all environment variable references using syntax %variable% like %host% are substituted by current value of the referenced environment variable. In this case %host% is most likely replaced by an empty string before FOR is executed at all if the environment variable host is not defined by chance on starting the batch file.
The help output on running set /? in a command prompt window explains when and how to use delayed expansion on an IF and a FOR example. In code above delayed environment variable expansion is enabled and used to reference the current value of environment variable host on iterations of the loop body command block on which the environment variable is defined and gets assigned a string value.
There would be also possible to use:
#echo off
echo %DATE% %TIME%
setlocal EnableExtensions DisableDelayedExpansion
set "DNS1=8.8.8.8"
set "DNS2=8.8.4.4"
for %%i in (%DNS1% %DNS2%) do (
echo ----------------
if %%i == 8.8.8.8 set "host=Google1"
if %%i == 8.8.4.4 set "host=Google2"
call echo tracert to %%host%%
tracert -d %%i
)
endlocal
echo %TIME%
exit /B
The command line call echo tracert to %%host%% is modified during the parsing step of entire command block by Windows command processor to call echo tracert to %host% and because of command CALL this command line is parsed a second time on each execution of the command block before ECHO command is executed resulting in printing the current value of environment variable host to console window.
But I suggest to use this much better code:
#echo off
echo %DATE% %TIME%
echo/
setlocal EnableExtensions DisableDelayedExpansion
set "DNS1=8.8.8.8=Google1"
set "DNS2=8.8.4.4=Google2"
for /F "tokens=2* delims==" %%I in ('set DNS 2^>nul') do (
echo ----------------
echo tracert to %%J
echo %SystemRoot%\System32\tracert.exe -d %%I
)
endlocal
echo/
echo %TIME%
exit /B
One or more IP addresses and their host names are assigned to one or more environment variables starting with the string DNS. IP address and host name are separated by an equal sign.
The command FOR runs in a separate command process started with cmd.exe /C in background the command line:
set DNS 2>nul
Command SET outputs to handle STDOUT (standard output) all environment variables starting with DNS sorted alphabetically with name=value which means for this example:
DNS1=8.8.8.8=Google1
DNS2=8.8.4.4=Google2
The error message output by SET to handle STDERR (standard error) on not finding any environment variable starting with the string DNS would be suppressed by this code by redirecting it to device NUL.
Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded set command line with using a separate command process started in background.
FOR with using option /F captures everything output to handle STDOUT in background command process and processes this output by ignoring empty lines and lines starting with a semicolon.
The captured lines start all with DNS and so there is definitely no line ignored as no line starts with a ;.
FOR with using option /F would also split each line into substrings using space/tab as delimiter with assigning just first substring to specified loop variable I. But this line splitting behavior is not useful for this task.
For that reason the option string "tokens=2* delims==" redefines the line splitting behavior. Now = is used as delimiter between the strings instead of space and tab.
And instead of assigning the first = delimited string to loop variable I which would be the name of the environment variable, the second equal sign delimited string is assigned to loop variable I because of tokens=2 which is the IP address.
And there is additionally assigned to next loop variable J according to ASCII table the rest of the line after the equal sign(s) after second = delimited string without any further string splitting on an equal sign. So the host name is assigned to loop variable J, even on containing one or more = as long as not containing them at beginning of host name.
This code is obviously better as the DNS environment variables can be defined all at top of the batch file with IP address and host name and nothing must be changed on the command lines below because it simply processes from 0 to n environment variables starting with DNS and having at least a second = delimited substring.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
exit /?
for /?
if /?
set /?
setlocal /?
tracert /?
im making an script to ping different websites. I want to read addresses from a file, ping them one time, and write the results on another text file.
echo off
cls
echo "TEST" > %cd%\out.txt
time >> %cd%\out.txt
ping -n 1 google.com>> %cd%\out.txt
pause>null
I dont know how to make the loop for pinging and also, how to read line by line from the file. Can anyone help me?
Thanks.
Something along the lines of the following should be what you want:
#echo off& setlocal
echo google.com>sites.txt
echo yahoo.com>>sites.txt
set cd=.
for /f %%w in (sites.txt) do call :NextSite %%w
exit /b
:NextSite
echo. >>%cd%\out.txt
echo. >>%cd%\out.txt
echo. | time | find "current" >>%cd%\out.txt
ping -n 1 %1 >>%cd%\out.txt
The logic starts at the line with the "for" statement; the preceding lines merely set up a test environment. You will have your own %cd% setting and filename to replace "sites.txt"
I am trying to get this script to jump to another section of the script if there is no input from the user.
Down at the if %input%== area.
What I'm trying to do is skip to the section where the script checks for .mp4 files and moves them if they are there. Am I supposed to set a variable or loop for that section? Thanks for any replies
#echo off
echo Checking for youtube-dl updates.
pause
youtube-dl -U
rem Enter the url or urls that you want to download from
set /p input="Enter the url(s) you want to download:"
rem Uses the youtube-dl continue (-c) option to download multiple files if not in a playlist
youtube-dl -c "%input%"
rem pause
if %input%=="" GOTO:EOF
cls
echo Download complete, please wait while files are transfered to appropiate folder
pause
for %%o in (.mp4) do move "*%%o" "E:\Documents\scripts\videos\"
if not exist do echo .mp4 files are no longer in this directory
pause
How about following script? This script waits for 3 seconds while "file.mp4" doesn't exist. It keeps to wait until the file exists. About "filename", you can change for your script.
#echo off
set waittime=3
set filename=file.mp4
:loop
if not exist %filename% (
Timeout /t %waittime% /nobreak > nul
goto loop
)
echo Find %filename%
When doing string comparison in batch you have to make sure, that both parts are equal, which in your case will never happen! In most languages strings have double quotes around them. In batch they usually do not.
To solve your problem enclose %input% in double quotes as well.
Note that it can be useful to do something like "x%input%"=="x" to prevent certain characters like <>|to be at the beginning of the comparison string.
You can check this on your own with these few lines:
#echo off
set /p input="Input something or nothing here "
echo %input%
echo "%input%"
pause
If you are hitting Return without any input you will see that only the bottom one will output "" which is the string you are comparing to.
I have set up a batch file to be default to open .txt files. In an earlier question I found out that %1 gives me the path of the file which was actually calling the batch file. The Problem is: if the file name contains white space, it gets interpreted as multiple parameters.
Example:
opening file "C:\Users\Desktop\space true.txt"
%1 gives:"C:\Users\Desktop\space" and then %2 gives: "true.txt"
How could I get just the full file path with the name and white space without trying to do a loop to attempt to get the full path by combining %1%2%3%4...
UPDATE-----------------------
Sorry there was a miss communication. The code below is working. The trick was to put "%*" instead of "%1"
here the code:
#echo on
set var= "%*"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar"%var%
pause
I do the whole changing the path, because the file which I double click and the the the batch file are in different directories. I had to change it to this.
UPDATE 2 --------------------------
The solution which worked best for me was from this fine gentlemen dbenham.
#echo off
pushd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" %*
The only complain I have is, that there is a case, where %* does not return the path with quotes. So I am searching for a final solution. Something like this "%~*" But this doesn't work.
Thanks in advance
The following is not quite correct - I thought the file associations would put quotes around the file name like drag and drop does. But I was mistaken
This line is the source of your problem:
set var= "%*"
When files are dragged onto your batch script, or if a text file is double clicked, any file name(s) containing space will automatically be enclosed within quotes.
When you add your own additional quotes, it defeats the purpose of the quotes - the space is no longer quoted.
For example, a string like "name with space.txt" is treated as a single arg, but with added quotes, ""name with space.txt"" becomes three arguments.
There is no need for your var variable. You can use %* directly in your START command.
#echo on
pushd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" %*
pause
I'm not sure the above works properly if multiple files are passed. I suspect you may want the following:
#echo on
pushd "C:\Users\MyText Editor"
for %%F in (%*) do start javaw -jar "MyTextEditor.jar" %%F
pause
There is one potential problem. Windows has a bug in that file names containing & are not automatically quoted as they should. See "Droplet" batch script - filenames containing ampersands for more info.
EDIT - The following should work
OK, I did some tests and I believe your best bet is to modify the command associated with .txt files.
I tested association changes via the command line. This must be done via an elevated command prompt with admin rights. On my machine I go to the Start menu, click on "All Programs", click on "Accessories" folder, right click "Command Prompt", and select "Run as administrator", then click "Yes" to allow the program to make changes to the system.
The following command will show which file type needs to be modified
assoc .txt
On my machine it reports .txt=txtfile, so txtfile is what must be modified using FTYPE.
I believe the following should work for you:
ftype txtfile="C:\pathToYourScrpt\yourScript.bat" "%1"
Obviously you would need to fix the path to your batch script :-)
Once you have made the change, the filename will automatically be quoted every time your script is invoked via a file association.
Your batch script can then look like the following, and it should work no matter how it is invoked (excepting drag and drop with file name containing & but no space):
#echo off
pushd "C:\Users\MyText Editor"
for %%F in (%*) do start javaw -jar "MyTextEditor.jar" %%F
It seems to me you should be able to eliminate the batch script and configure FTYPE TXTFILE to open your java editor directly. I should think something like the following:
ftype txtfile="c:\pathToJava\javaw.exe" -jar "C:\Users\MyText Editor\MyTextEditor.jar" "%1"
When calling your batch file, you must enclose your parameter in quotes if there is spaces in it.
E.g.: Batch.cmd "C:\Users\Desktop\space true.txt"
Eric
%*
Here's a list of characters.
& seperates commands on a line.
&& executes this command only if previous command's errorlevel is 0.
|| (not used above) executes this command only if previous command's errorlevel is NOT 0
> output to a file
>> append output to a file
< input from a file
| output of one command into the input of another command
^ escapes any of the above, including itself, if needed to be passed to a program
" parameters with spaces must be enclosed in quotes
+ used with copy to concatinate files. E.G. copy file1+file2 newfile
, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,
%variablename% a inbuilt or user set environmental variable
!variablename! a user set environmental variable expanded at execution time, turned with SelLocal EnableDelayedExpansion command
%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.
%* (%*) the entire command line.
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.
Your problem is really that the syntax of your set command is wrong. In a batch
file, a set command looks like this:
set "var=%1"
That will give you your variable exactly as received. If the user quoted it,
then the variable's value will have quotes around it. To remove the quotes,
you'd put a ~ in front of the number:
set "var=%~1"
Notice how the quotes go around the entire assignment, and not just around the
value you are assigning. It is not set var="%1".
If you use set var= "%*", you haven't really fixed the fundamental problem
that your syntax is wrong. Plus, often you really do want %1 and not the
entire command line.
Here is an example script to test various quoting behaviors:
#echo off
set var="%*"
echo 1. var="%%*" --^> [%var%] (wrong)
set "var=%*"
echo 2. "var=%%*" --^> [%var%]
set "var=%1"
echo 3. "var=%%1" --^> [%var%]
set "var=%~1"
echo 4. "var=%%~1" --^> [%var%]
set "var=%~2"
echo 5. "var=%%~2" --^> [%var%]
set "var=%~3"
echo 6. "var=%%~3" --^> [%var%]
And here is the output of that script. Note how arg1, arg2, and arg3 are all
quoted:
C:\batch> all_args.cmd "arg 1" "this is arg 2" "arg 3"
1. var="%*" --> [""arg 1" "this is arg 2" "arg 3""] (wrong)
2. "var=%*" --> ["arg 1" "this is arg 2" "arg 3"]
3. "var=%1" --> ["arg 1"]
4. "var=%~1" --> [arg 1]
5. "var=%~2" --> [this is arg 2]
6. "var=%~3" --> [arg 3]
You can see that numbers 4, 5, and 6 correctly pulled out their quoted arguments
and saved the value into var. You typically want to save the argument without quotes, and then quote it when you use it in your script. In other words, your script should look like this:
#echo on
set "var=%~1"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" "%var%"
pause
#echo on
set var= "%*"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar"%var%
pause
Becomes removing redundant commands
start "" javaw -jar "C:\Users\MyText Editor\MyTextEditor.jar" "%*"
pause
Echo is already on unless turned off by you.
We don't put things into variables for no reason, and it's already in %*. It just makes convoluted code and removes meaning from the name of the variable.
When programming (unlike typing) we don't change paths (and cd /d C:\Users\MyText Editor does drive and folder anyway).
We specify full path on the command line. This makes your meaning quite clear.
The main problem was there was no space between .jar and %var% and start command the first quotes on the line are assumed to the CMD's window title. I would code the path to javaw and not use start. Start is asking the Windows' graphical shell to start the file, not CMD.
Here's a batch file that starts vbs files. I don't specify path to cscript as it's a Windows' command.
It's complexity is to make use fairly idiot proof and easy for others.
#echo off
Rem Make sure filter.vbs exists
set filter=
set filterpath=
Call :FindFilter filter.vbs
Rem Add filter.bat to the path if not in there, setx fails if it's already there
setx path %~dp0;%path% 1>nul 2>nul
Rem Test for some command line parameters
If not "%1"=="" goto main
echo.
echo -------------------------------------------------------------------------------
echo.
echo Filter.bat
echo ==========
echo.
echo The Filter program is a vbs file for searching, replacing, extracting, and
echo trimming console output and text files.
echo.
echo Filter.bat makes Filter.vbs easily usable from the command line. It
echo controls unicode/ansi support and debugging.
echo.
echo Type Filter Help or Filter HTMLHelp for more information.
echo.
cscript //nologo "%filter%" menu
Goto :EOF
:Main
echo %date% %time% %~n0 %* >>"%~dp0\FilterHistory.txt"
rem echo Batch file ran
rem echo %*
Rem /ud Unicode and Debug
If %1==/ud FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u //x %%j&Goto :EOF
Rem /u Unicode
If %1==/u FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u %%j&Goto :EOF
Rem /d Ansi Debug
If %1==/d FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //x %%j&Goto :EOF
Rem -ud Unicode and Debug
If %1==-ud FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u //x %%j&Goto :EOF
Rem /u Unicode
If %1==-u FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u %%j&Goto :EOF
Rem -d Ansi Debug
If %1==-d FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //x %%j&Goto :EOF
Rem ANSI
cscript "%filter%
" //nologo %*&Goto :EOF
Goto :EOF
:FindFilter
If Exist "%~dpn0.vbs" set filter=%~dpn0.vbs&set filterpath=%~dp0&goto :EOF
echo find filter 1
If Not "%~dpnx$PATH:1" == "" set filter=%~dpnx1&set filterpath=%~dp1&goto :EOF
echo find filter 2
If Exist "%temp%\filter.vbs" set filter=%temp%\filter.vbs&set filterpath=%temp%&goto :EOF
copy "%~dpnx0" "%~dpn0.bak"
if not errorlevel 1 (
echo creating "%~dpn0.vbs"
goto :EOF
)
copy "%~dpnx0" "%temp%\filter.bak"
echo Error %errorlevel%
if not errorlevel 1 (
echo creating "%temp%\filter.bak"
Goto :EOF
)
Goto :EOF
I have a batch file and I want to include an external file containing some variables (say configuration variables). Is it possible?
Note: I'm assuming Windows batch files as most people seem to be unaware that there are significant differences and just blindly call everything with grey text on black background DOS. Nevertheless, the first variant should work in DOS as well.
Executable configuration
The easiest way to do this is to just put the variables in a batch file themselves, each with its own set statement:
set var1=value1
set var2=value2
...
and in your main batch:
call config.cmd
Of course, that also enables variables to be created conditionally or depending on aspects of the system, so it's pretty versatile. However, arbitrary code can run there and if there is a syntax error, then your main batch will exit too. In the UNIX world this seems to be fairly common, especially for shells. And if you think about it, autoexec.bat is nothing else.
Key/value pairs
Another way would be some kind of var=value pairs in the configuration file:
var1=value1
var2=value2
...
You can then use the following snippet to load them:
for /f "delims=" %%x in (config.txt) do (set "%%x")
This utilizes a similar trick as before, namely just using set on each line. The quotes are there to escape things like <, >, &, |. However, they will themselves break when quotes are used in the input. Also you always need to be careful when further processing data in variables stored with such characters.
Generally, automatically escaping arbitrary input to cause no headaches or problems in batch files seems pretty impossible to me. At least I didn't find a way to do so yet. Of course, with the first solution you're pushing that responsibility to the one writing the config file.
If the external configuration file is also valid batch file, you can just use:
call externalconfig.bat
inside your script. Try creating following a.bat:
#echo off
call b.bat
echo %MYVAR%
and b.bat:
set MYVAR=test
Running a.bat should generate output:
test
Batch uses the less than and greater than brackets as input and output pipes.
>file.ext
Using only one output bracket like above will overwrite all the information in that file.
>>file.ext
Using the double right bracket will add the next line to the file.
(
echo
echo
)<file.ext
This will execute the parameters based on the lines of the file. In this case, we are using two lines that will be typed using "echo". The left bracket touching the right parenthesis bracket means that the information from that file will be piped into those lines.
I have compiled an example-only read/write file. Below is the file broken down into sections to explain what each part does.
#echo off
echo TEST R/W
set SRU=0
SRU can be anything in this example. We're actually setting it to prevent a crash if you press Enter too fast.
set /p SRU=Skip Save? (y):
if %SRU%==y goto read
set input=1
set input2=2
set /p input=INPUT:
set /p input2=INPUT2:
Now, we need to write the variables to a file.
(echo %input%)> settings.cdb
(echo %input2%)>> settings.cdb
pause
I use .cdb as a short form for "Command Database". You can use any extension.
The next section is to test the code from scratch. We don't want to use the set variables that were run at the beginning of the file, we actually want them to load FROM the settings.cdb we just wrote.
:read
(
set /p input=
set /p input2=
)<settings.cdb
So, we just piped the first two lines of information that you wrote at the beginning of the file (which you have the option to skip setting the lines to check to make sure it's working) to set the variables of input and input2.
echo %input%
echo %input2%
pause
if %input%==1 goto newecho
pause
exit
:newecho
echo If you can see this, good job!
pause
exit
This displays the information that was set while settings.cdb was piped into the parenthesis. As an extra good-job motivator, pressing enter and setting the default values which we set earlier as "1" will return a good job message.
Using the bracket pipes goes both ways, and is much easier than setting the "FOR" stuff. :)
So you just have to do this right?:
#echo off
echo text shizzle
echo.
echo pause^>nul (press enter)
pause>nul
REM writing to file
(
echo XD
echo LOL
)>settings.cdb
cls
REM setting the variables out of the file
(
set /p input=
set /p input2=
)<settings.cdb
cls
REM echo'ing the variables
echo variables:
echo %input%
echo %input2%
pause>nul
if %input%==XD goto newecho
DEL settings.cdb
exit
:newecho
cls
echo If you can see this, good job!
DEL settings.cdb
pause>nul
exit
:: savevars.bat
:: Use $ to prefix any important variable to save it for future runs.
#ECHO OFF
SETLOCAL
REM Load variables
IF EXIST config.txt FOR /F "delims=" %%A IN (config.txt) DO SET "%%A"
REM Change variables
IF NOT DEFINED $RunCount (
SET $RunCount=1
) ELSE SET /A $RunCount+=1
REM Display variables
SET $
REM Save variables
SET $>config.txt
ENDLOCAL
PAUSE
EXIT /B
Output:
$RunCount=1
$RunCount=2
$RunCount=3
The technique outlined above can also be used to share variables among multiple batch files.
Source: http://www.incodesystems.com/products/batchfi1.htm
Kinda old subject but I had same question a few days ago and I came up with another idea (maybe someone will still find it usefull)
For example you can make a config.bat with different subjects (family, size, color, animals) and apply them individually in any order anywhere you want in your batch scripts:
#echo off
rem Empty the variable to be ready for label config_all
set config_all_selected=
rem Go to the label with the parameter you selected
goto :config_%1
REM This next line is just to go to end of file
REM in case that the parameter %1 is not set
goto :end
REM next label is to jump here and get all variables to be set
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set sister=Anna
rem This next line is to skip going to end if config_all label was selected as parameter
if not "%config_all_selected%"=="1" goto :end
:config_test
set "test_parameter_all=2nd set: The 'all' parameter WAS used before this echo"
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:config_color
set first_color=blue
set second_color=green
if not "%config_all_selected%"=="1" goto :end
:config_animals
set dog=Max
set cat=Miau
if not "%config_all_selected%"=="1" goto :end
:end
After that, you can use it anywhere by calling fully with 'call config.bat all' or calling only parts of it (see example bellow)
The idea in here is that sometimes is more handy when you have the option not to call everything at once. Some variables maybe you don't want to be called yet so you can call them later.
Example test.bat
#echo off
rem This is added just to test the all parameter
set "test_parameter_all=1st set: The 'all' parameter was NOT used before this echo"
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
call config.bat animals
echo Yesterday %father% and %mother% surprised %sister% with a cat named %cat%
echo Her brother wanted the dog %dog%
rem This shows you if the 'all' parameter was or not used (just for testing)
echo %test_parameter_all%
call config.bat color
echo His lucky color is %first_color% even if %second_color% is also nice.
echo.
pause
Hope it helps the way others help me in here with their answers.
A short version of the above:
config.bat
#echo off
set config_all_selected=
goto :config_%1
goto :end
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set daughter=Anna
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:end
test.bat
#echo off
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
echo %father% and %mother% have a daughter named %daughter%
echo.
pause
Good day.
The best option according to me is to have key/value pairs file as it could be read from other scripting languages.
Other thing is I would prefer to have an option for comments in the values file - which can be easy achieved with eol option in for /f command.
Here's the example
values file:
;;;;;; file with example values ;;;;;;;;
;; Will be processed by a .bat file
;; ';' can be used for commenting a line
First_Value=value001
;;Do not let spaces arround the equal sign
;; As this makes the processing much easier
;; and reliable
Second_Value=%First_Value%_test
;;as call set will be used in reading script
;; refering another variables will be possible.
Third_Value=Something
;;; end
Reading script:
#echo off
:::::::::::::::::::::::::::::
set "VALUES_FILE=E:\scripts\example.values"
:::::::::::::::::::::::::::::
FOR /F "usebackq eol=; tokens=* delims=" %%# in (
"%VALUES_FILE%"
) do (
call set "%%#"
)
echo %First_Value% -- %Second_Value% -- %Third_Value%
While trying to use the method with excutable configuration
I noticed that it may work or may NOT work
depending on where in the script is located the call:
call config.cmd
I know it doesn't make any sens, but for me it's a fact.
When "call config.cmd" is located at the top of the
script, it works, but if further in the script it doesn't.
By doesn't work, I mean the variable are not set un the calling script.
Very very strange !!!!