Simple SET not working in batch file - variables

Disclaimer: I'm not a batch files guru, just digging my way with the help of Google and SO. Also note that I'm trying to run this batch file as a Custom Action in SourceTree.
The following simple SET command doesn't seem to assign value to the variable:
SET MYVAR = %1
ECHO "%MYVAR%"
ECHO "!MYVAR!"
ECHO %1
The first ECHO above returns ""; the second one "!MYVAR!", whereas the last one returns the actual value of command-line parameter. How can I assign value to MVAR?

set is sensitive to spaces on each side of the =. You are setting a variable named myvar[Space}

Related

Execute a program with a parameter from a *.bat file

I would like your help with an issue.
I have a VB application located into a foler:
C:\folder\program.exe
I need to execute it using a *.bat file, but I also need to send a parameter like this:
CompRate&--&C:\folder\subfolder\CompRate&--&False&--&
When I execute the application using the IDE (VS2010) it goes to a Case statement (in this case 'CompRate') and generates a file with the same name into the folder 'C:\folder\subfolder\'
I have tried in the bat file this:
"C:\folder\program.exe" "CompRate&--&C:\folder\subfolder\CompRate&--&False&--&"
this
"C:\folder\program.exe" CompRate&--&C:\folder\subfolder\CompRate&--&False&--&
and other options.
Escape ampersands with ^
& 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.
.
--

Using variable in sub-string operation in batch file FOR loop

I am trying to use the FIXED_LENGTH variable within a FOR loop.
Using the length of the string directly in the loop results in correct result, however trying to use the variable does not work. Any ideas?
Snippet that provides correct result
SETLOCAL ENABLEDELAYEDEXPANSION
REM Loop through the input file and read each line.
FOR /F %%G IN (SVN_URLs_List.txt) DO (
SET CUR_LINE=%%G
REM Make sure the variable CUR_LINE is surrounded with ! instead of % to ensure delayed variable expansion.
#ECHO Processing the line: !CUR_LINE!
REM Set fixed length of "https://projects.abcdefg.com/subversion/"
SET FIXED_LENGTH=40
REM Get the sub-string of CUR_LINE to get the folder name.
SET FOLDER_NAME=!CUR_LINE:~40!
#ECHO !FOLDER_NAME!
)
ENDLOCAL
Snippet that does NOT produce correct result:
SETLOCAL ENABLEDELAYEDEXPANSION
REM Loop through the input file and read each line.
FOR /F %%G IN (SVN_URLs_List.txt) DO (
SET CUR_LINE=%%G
REM Make sure the variable CUR_LINE is surrounded with ! instead of % to ensure delayed variable expansion.
#ECHO Processing the line: !CUR_LINE!
REM Set fixed length of "https://projects.abcdefg.com/subversion/"
SET FIXED_LENGTH=40
REM Get the sub-string of CUR_LINE to get the folder name.
SET FOLDER_NAME=!CUR_LINE:~!!FIXED_LENGTH!!!
#ECHO !FOLDER_NAME!
)
ENDLOCAL
I have tried
SET FOLDER_NAME=!CUR_LINE:~!!FIXED_LENGTH!!!
SET FOLDER_NAME=!CUR_LINE:~!FIXED_LENGTH!!
SET FOLDER_NAME=!CUR_LINE:~%FIXED_LENGTH%!
The input in the SVN_URLs_List.txt looks like:
https://projects.abcdefg.com/subversion/svnrepo1
https://projects.abcdefg.com/subversion/svn_repo_2
https://projects.abcdefg.com/subversion/another repo 3
I am expecting result:
svnrepo1
svn_repo_2
another repo 3
The first snippet produces right results.
However using the second snippet produces something like:
https://projects.abcdefg.com/subversion/svnrepo1FIXED_LENGTH
https://projects.abcdefg.com/subversion/svn_repo_2FIXED_LENGTH
https://projects.abcdefg.com/subversion/another repo 3FIXED_LENGTH
SET FOLDER_NAME=!CUR_LINE:~!!FIXED_LENGTH!!!
SET FOLDER_NAME=!CUR_LINE:~!FIXED_LENGTH!!
Wrong syntax. Where does the variable reference begin/end? The parser can not determine it.
SET FOLDER_NAME=!CUR_LINE:~%FIXED_LENGTH%!
Almost, the parse can handle this syntax but bad behaviour. As the variable (FIXED_LENGTH) is assigned its value inside of the for code block, and as the parser replaced the read operation on the variable with its value at parse time (no delayed expansion syntax used to read the variable value) before the variable was assigned its value, the operation will fail.
In your case, instead of defining the FIXED_LENGTH variable inside the for loop, you can define the variable before the for loop, out of it. So, when the block of lines in the do clause of the for command is parsed, the variable will have the adecuated value.
If you prefer/need to declare the variable inside the for loop, you will have to use something like
for %%a in (!FIXED_LENGTH!) do SET FOLDER_NAME=!CUR_LINE:~%%a!
That way the read operation on FIXED_LENGTH is delayed, assigned to the replaceable parameter of the for loop and this parameter is used instead of the variable reference in the substring operation.

How would I call a dynamic variable name?

Okay, so I'm trying to make a program that "understands" user input and does what they tell it to do. People usually just use specific commands such as "open this file" and it only works if the user types EXACTLY that. I'm trying to give my users a little bit of leeway, so that they can type something like what they want to happen, and the computer will get the general idea. With that block of rambling aside, I've run into a problem.
set word%wordNum%=%word%
:fileExtension
set extChk= %letterNum% - 2 REM Includes the period of the extension
call set extension=%%_albaiRec:~%extChk%,4%%
::extChk is checking for a period so the program will recognize a file extension
set file=
That last line is where I get stuck...
I'm trying to use that last recorded word variable.
set var=7
set word7=Wanted text
echo %word%var%%
Sorta like that?
Add setLocal enableDelayedExpansion to the start of your script.
Then replace echo %word%var%% with echo !word%var%!.
For more information - http://ss64.com/nt/delayedexpansion.html

How to override batch variable number of characters limit?

I'm having an issue on the current project I'm working on.
I have to get a query stored from a file into a variable, whose file only contains a query (It is generated by part of the program). For instance I use the following code:
set /p query=<path\to\my\folder\fileContainingQuery.soql
It works when the query isn't that long, but when its length is beyond 1024 characters, the query is truncated and since I gotta send it to another configuration file using the FART tool, that's quite not convenient.
How to override this problem?
There is a limit in how many data can be stored in a environment variable. In theory, the maximum length is 32767 characters, BUT a batch file cannot set a variable that is longer than the maximum command line length (8192).
You can use a for /f command to read the line
for /f "usebackq delims=" %%f in ("path\to\my\folder\fileContainingQuery.soql") do set "q=%%f"
Or you can generate a auxiliary batch file to assign the content of the query
<nul set/px=set q=>sql.set.cmd
type "path\to\my\folder\fileContainingQuery.soql">>sql.set.cmd
call sql.set.cmd
And both will get the maximum possible text into the variable ONLY if the final command line is not too big (8186 characters in my tests). In other case, nothing is retrieved.
BUT, once the value has been retrieved, is has to be used inside a command. And here the same limitation happens. 8192 is the maximum line length and the content of the variable IS inside the line.
So, your final limit for the length of the query is less than that.
#MC ND: Thanks for your answer, I used the for /f command this way after thinking back at it. (Didn't read your answer at this moment).
(for /f "delims=" %%b in (path\to\my\folder\fileContainingQuery.soql) do (
set query=%%b
))
echo %query%
My hypothesis for my previous problem is that the set /p var function may only accept 1024 characters on user input, and as my query file only contains one line which length could be greater than this limit, it truncates the query. The above code works fine for me and I get my complete query in the variable.

Variable assignment in batch

This question seems to be (very) stupid be I can't deal with it :(
When I tried this batch code:
if "%1" == "-i" (
set is = %2
echo. %is%
shift
)
called with 2 (or more) arguments, it does NOT work. It actually prints a blank. The "shift" command is not done either. When I watch the executed code (without the #echo off at the beginning), I can see that the "set" command is completed.
What's wrong with it?
Example of calling:
c:\script.bat -i test -d bla
You have two issues. By default group of statements in parens will have variable expansion done all at once, that is before your set command. Also the semantics for set is wrong, you don't want spaces around the =.
Add this to the top of your file:
setlocal ENABLEDELAYEDEXPANSION
and remove the spaces around = in set:
set is=%2
Finally used delayed expansion:
echo. !is!
A possible third issue is you may need two SHIFTs, one for -i, one for it's is argument.
Update
Thanks to #dbenham for pointing out that it wasn't a syntax error with set, it's just surprising behavior that deserves a little explanation. If you execute these commands:
set a=one
echo "%a%"
The result is:
"one"
That makes sense, but try:
set b = two
echo "%b%"
And you get:
"%b%"
What? This is what you would expect when environment var b is unset. But we just set it. Or did we:
echo "%b %"
Displays:
" two"
For the Windows set command, unlike any other language or environment I'm aware of, the spaces are significant. The spaces before the = become part of the environment var name, spaces after become part of the value. This uncommon behavior is a common source of errors when writing Windows batch programs.