Why are passed values in a batch %variable% not applied correctly? - windows

[Original Title: Why are lowercase values in a batch %variable% being returned as uppercase?]
Condition
I have a batch file where the value is declared for a variable as such:
SET myVar="something.lowercase"
But later in the script when you reference that variable as such:
%myVar%
the value is coming in as SOMETHING.LOWERCASE which is causing the particular command to not work correctly. (see resolution: the issue was a spurious " in the command and the uppercase was the way the "failure" was being reported)
Concern
Why and under what situation does this happen? moot as the value is not being changed, but rather the way the failure is reported and the failure was due to a " being introduced in the passed value (see resolution)
Context
For context, in case it matters, it is being called in this way: (it turned out to matter as the introduced " was causing the check to fail and the confusion was coming from the "cannot find ..." being uppercase)
TASKLIST /FI "IMAGENAME eq %myVar%" 2>NUL | FIND /I /N "%myVar%">NUL
I suspect that this is somehow happening in the context of this command, but cannot be sure and don't know why. If that is by chance the case, how can I mitigate it? (see resolution)
Thank you in advance.
Resolution
Thanks to #Campo's suggestion, changing the value by dropping the " resolved the issue and the script functions correctly now. Thank you.

Your issue is because you're needlessly including doublequotes in your variable value.
Because you've included the doublequotes the TaskList filter is looking for:
"IMAGENAME eq "something.lowercase""
...and your Find command is trying to match:
""something.lowercase""
The fix is to use the correct syntax for setting a variable:
Set "myVar=something.lowercase"

Related

How to assign a command line parameter which contains ! and & to a variable?

Please consider the following very simple batch script (the file is named test.cmd):
#echo off
set "var1=%~1"
echo %var1%
The script should be called with one command line parameter, should assign the string which is contained in that parameter to a variable, and should output the variable.
As expected, I get an error message when I call this script with a command line parameter which contains an ampersand (&):
C:\Batch>test "a&b"
a
'b' is not recognized as an internal or external command,
operable program or batch file.
The reason for this has been discussed in some other questions here and elsewhere, for example that one; the usual remedy is to use delayed expansion. So I changed the script accordingly:
#echo off
setLocal enableDelayedExpansion
set "var1=%~1"
echo !var1!
Now it works with the parameter from before:
C:\Batch>test "a&b"
a&b
But there is a new problem. When the command line parameter contains an exclamation mark (!), it will be dropped from the output:
C:\Batch>test a!b
ab
This behavior also has been discussed at several places, for example here; the crucial thing to note is that dropping the exclamation mark happens during the assignment, not during the echo.
Despite a lot of research, I did not find a question here which provided an elegant solution for both problems at once. That is, is there an elegant way to assign a command line parameter to a variable when that parameter contains an ampersand AND an exclamation mark?
It seems that I need the delayed expansion to treat the ampersand correctly, but this destroys the exclamation mark.
The only solution I currently see is to not use delayed expansion and to add code to explicitly quote all ampersands in the input string. This would be so ugly that I seriously think that I am missing something here.
As a side note, the reason for the problem actually seems to be that there (IMHO!) is no way to get the command line parameter in a delayed-expanded fashion. The syntax for the first parameter is %~1, there is no such thing as !~1.
Move the setLocal enableDelayedExpansion after the the set„ that's all.
#echo off
set "var1=%~1"
setLocal enableDelayedExpansion
echo !var1!

Using a .bat file, I need to extract information after ")" punctuation from a variable and store it in another variable?

I have a variable from a text file.
set /p namz=<"playersname.txt"
Right now if I echoed this, it would echo the entire contents of the file.
The Contents of playersname.txt include the following,
theplayernameis:Player One
I need a code that I can use in .bat to help me to extract everything after the ":" from the .txt file while ignoring everything else before it, "Player One" then it needs to store it in another variable which I can call upon anytime I want it.
I've been racking my brain on this, trying to come up with a solution, been forum hopping for a long time, haven't quite found what I needed yet. Please help..
You have a single-line textfile, you need the second token after a delimiter that might be : or /:
for /f "tokens=2 delims=:/" %%a in (playersname.txt) do set namz=%%a
add every possible delimter to delims=

") was unexpected at this time", Create list of files in a variable - Batch

So I am trying to create a batch file, that gets all the files in deletesrc and find's if it's name matches any folder in deletedest. To accomplish this, I have tried to generate a list of file names in deletesrc which is stored in deletefiles (in the format "first" "second" "third file"). Then I intend to loop through each folder in deletedest and check for it's existence in deletesrc (using this). So far I have managed:
setlocal enabledelayedexpansion
set "deletesrc=F:\Delete Source"
set "deletedest=C:\Users\Spaced Name\Delete\Dest"
set "deletefiles=" ::I think this is useless, but I would prefer it to be here
for /R "%deletesrc%\" %%i in (*) do (
set "deletefiles=!deletefiles!^"%%i^" "
::random comment that is source of error
)
set deletefiles=!deletefiles!:rTrim
echo !deletefiles!
The main problem is, I keep getting ) was unexpected at this time.
Placing an echo test as the first thing within the loop, does not change the output, implying the loop is not run and the error encountered first. Placing an echo just before the loop, does produce output and the error immediately after it.
If there are any syntax standards or things I should/should not be doing that do not answer the question, I would like to know.
Your problem is you're using :: as a comment inside your FOR loop. You can't do this because :: is actually the label designator and it is breaking the FOR loop.
Change this line:
::random comment that is source of error
To this:
REM random comment that is source of error
UPDATE
As foxidrive stated in the comments, you can use :: as a comment inside a FOR as long as it is not the last line before the closing ).
Try this:
set deletefiles=!deletefiles! "%%i"

CMD appears not to recognize variables

CMD does not appear to be recognizing any variable I store using SET. If I run this batch file:
#ECHO off
SET /P name = What is your name?
ECHO %name%
PAUSE
ECHO on
I get the following output:
What is your name? steven
ECHO is off.
Press any key to continue . . .
When I run line 2 and then line 3 from the command prompt, it just prints:
%name%
Do I have something configured incorrectly? Am I correct in thinking that line 2 should create a session variable that should be recognized in line 3?
I searched, but I could only find answers related to variable expansion within IF blocks. This is happening to me outside any IF/FOR/etc blocks.
This is Windows 7, by the way. I'm not sure how much cmd changes from one version of Windows to another.
There must not be any spaces around the equal sign in the set instruction. Change this
SET /P name = What is your name?
into this
SET /P name=What is your name?
and your problem will disappear.
since I can not add any comments yet I have to post a new answer. The information:
"There must not be any spaces around the equal sign in the set instruction."
is only partly correct. To be exact it should say: the equal sign must follow directly after the variable name (in sricks3's case without a space). Whatever comes after the equal sign will be used as input-prompt for the variable including any spaces, so the following code will work as well:
SET /P name= What is your name?

Check for null variable in Windows batch

I'm working on a Windows batch file that will bcp three text files into SQL Server. If something goes wrong in production, I want to be able to override the file names. So I'm thinking of doing something like this.
bcp.exe MyDB..MyTable1 in %1 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable2 in %2 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable3 in %3 -SMyServer -T -c -m0
I would like to be able to enter default names for all three files, to be used if the positional parameters are not supplied. The idea would be either to execute
myjob.bat
with no parameters, and have it use the defaults, or execute
myjob.bat "c:\myfile1" "c:\myfile2" "c:\myfile3"
and have it use those files. I haven't been able to figure out how to tell if %1, %2 and %3 exist and/or are null. I also don't know how to set those values conditionally. Is this possible? Any suggestions would be appreciated.
To test for the existence of a command line paramater, use empty brackets:
IF [%1]==[] echo Value Missing
or
IF [%1] EQU [] echo Value Missing
The SS64 page on IF will help you here. Under "Does %1 exist?".
You can't set a positional parameter, so what you should do is do something like
SET MYVAR=%1
You can then re-set MYVAR based on its contents.
The right thing would be to use a "if defined" statement, which is used to test for the existence of a variable. For example:
IF DEFINED somevariable echo Value exists
In this particular case, the negative form should be used:
IF NOT DEFINED somevariable echo Value missing
PS: the variable name should be used without "%" caracters.
Both answers given are correct, but I do mine a little different. You might want to consider a couple things...
Start the batch with:
SetLocal
and end it with
EndLocal
This will keep all your 'SETs" to be only valid during the current session, and will not leave vars left around named like "FileName1" or any other variables you set during the run, that could interfere with the next run of the batch file. So, you can do something like:
IF "%1"=="" SET FileName1=c:\file1.txt
The other trick is if you only provide 1, or 2 parameters, use the SHIFT command to move them, so the one you are looking for is ALWAYS at %1...
For example, process the first parameter, shift them, and then do it again. This way, you are not hard-coding %1, %2, %3, etc...
The Windows batch processor is much more powerful than people give it credit for.. I've done some crazy stuff with it, including calculating yesterday's date, even across month and year boundaries including Leap Year, and localization, etc.
If you really want to get creative, you can call functions in the batch processor... But that's really for a different discussion... :)
Oh, and don't name your batch files .bat either.. They are .cmd's now.. heh..
Hope this helps.
rem set defaults:
set filename1="c:\file1.txt"
set filename2="c:\file2.txt"
set filename3="c:\file3.txt"
rem set parameters:
IF NOT "a%1"=="a" (set filename1="%1")
IF NOT "a%2"=="a" (set filename2="%2")
IF NOT "a%3"=="a" (set filename1="%3")
echo %filename1%, %filename2%, %filename3%
Be careful with quotation characters though, you may or may not need them in your variables.
Late answer, but currently the accepted one is at least suboptimal.
Using quotes is ALWAYS better than using any other characters to enclose %1.
Because when %1 contains spaces or special characters like &, the IF [%1] == simply stops with a syntax error.
But for the case that %1 contains quotes, like in myBatch.bat "my file.txt", a simple IF "%1" == "" would fail.
But as you can't know if quotes are used or not, there is the syntax %~1, this removes enclosing quotes when necessary.
Therefore, the code should look like
set "file1=%~1"
IF "%~1"=="" set "file1=default file"
type "%file1%" --- always enclose your variables in quotes
If you have to handle stranger and nastier arguments like myBatch.bat "This & will "^&crash
Then take a look at SO:How to receive even the strangest command line parameters?

Resources