How to send command line arguments to batch file containing "=" char - batch-file

I want to invoke a batch file(tomcat's startup.bat) by passing a command line argument something like c:>startup.bat -Dsun.lang.ClassLoader.allowArraySyntax=true
But the "=" symbol is being replaced with a space.
If I put c:>startup.bat -D"sun.lang.ClassLoader.allowArraySyntax=true" the value was not set properly.
I am using Windows 7.
Is there anyway to pass command line arguments containing "="?
Thanks,
Siva

You can't do much about it inside the batch file, except change %1 to %1=%2, which only works if you know exactly how many parameters you're passing in, or you know they will always come in pairs. (I suppose you could loop and put together all of the -Dxxx parameters with the next parameter, and put those without a leading -D, but if you have other =-style parameters it can get really messy.)
But you can do something outside the batch file, by putting your parameter in quotes:
startup "-Dsun.lang.ClassLoader.allowArraySyntax=true"

You can use %* for all parameters.
In your batch
#echo off
javac %*
Or you can enquote your complete parameter
startup.bat "-Dsun.lang.ClassLoader.allowArraySyntax=true"
And startup.bat looks like (the %~1 removes surrounding quotes from %1)
#echo off
javac %~1

Related

Is it possible to run two batch files from Jenkins?

I have the following case. In jenkins I have one build which is running on different envoironments. That's why I have build with parameters with two options PROD/TEST. The build is invoking shell script with parameter PROD or TEST.
Here is example of the script A which jenkins is invoking:
if %1%==TEST(
start F:\test.bat
)
The script A itself is invoking another script - B.
Here is example of script B:
copy test.xt copyFolder\
The problem is that Jenkins only invoking the first script - A - and the second script B doesn't run.
Why does this happen?
You will need to call the batch file, not start it because it creates a new cmd.exe instance, so it can run a called batch file asynchronously (as mentioned by jeb here):
if "%~1" == "TEST" (
call F:\test.bat
)
Here, I want to note some things:
%1% will be interpreted as the first argument of the batch file (if any) and an extra percent-sign (%). You probably wanted here the first argument, so I have replaced %1% with %1. If it is not this what you wanted, then replace it with your variable name, but remember that it should not start with a number!
%1 was replaced by %~1 and quoted because:
%~1 means the first argument without any surrounding quotes.
Quoting the values in an if statement is always the best practice, but if there were quotes, the comparison would fail.
Added a space between ==, just to make the code clearer.
For an one-liner, see aschipfl's comment, it is:
if /I "%~1"=="TEST" (call "F:\test.bat")
See call /? and if /? in cmd for more information about how these commands work.

Escape characters of a file path argument for a batch file

I was making a batch file to take dragged-and-dropped folders for program input. Everything was working fine until I passed a folder, which for the sake of this post, called foo&bar.
Checking what %1 contained inside the batch file looked like C:\path\to\foo or C:\path\to\foo\foo. If the file path were in quotes it would work, so the only working code that slightly takes this into effect is :
set arg1=%1
cd %arg1%*
set arg1="%CD%"
Which changes directory to the passed argument using wildcards. However this only works once for if there is another folder with un-escaped characters inside the parent folder, passing the child folder would result in the parent folders' value.
I tried the answer of this post, which suggests to output the argument using a remark and redirection statement during an #echo on sequence. However no progress occurred in rectifying the problem. Any suggestions?
To recap, I am looking for ways to pass folders with un-escaped characters as arguments to a batch file. The implementation should preferably be in a batch file, but answers using VBScript are welcome. However the starting program must be in batch as this is the only program of the 3 that accepts files as arguments.
To test this, create a batch file with following code:
#echo off
set "arg1=%~1"
echo "the passed path was %arg1%"
pause
Then create folders called foobar and foo&bar. Drag them onto the batch file to see their output. foo&bar will only return C:\path\to\foo.
OK, so the problem is that Explorer is passing this as the command line to cmd.exe:
C:\Windows\system32\cmd.exe /c ""C:\path\test.bat" C:\path\foo&bar"
The outermost quotes get stripped, and the command becomes
"C:\working\so46635563\test.bat" C:\path\foo&bar
which cmd.exe interprets similarly to
("C:\working\so46635563\test.bat" C:\path\foo) & bar
i.e., bar is considered to be a separate command, to be run after the batch file.
The best solution would be to drag-and-drop not directly onto the batch file but onto, say, a vbscript or a Powershell script or a plain old executable. That script could then run the batch file, either quoting the argument appropriately or putting the directory path into an environment variable rather than on the command line.
Alternatively, you can retrieve the original command string from %CMDCMDLINE% like this:
setlocal EnableDelayedExpansion
set "dirname=!CMDCMDLINE!"
set "dirname=%dirname:&=?%"
set "dirname=%dirname:" =*%"
set "dirname=%dirname:"=*%"
set "dirname=%dirname: =/%"
for /F "tokens=3 delims=*" %%i in ("%dirname%") do set dirname=%%i
set "dirname=%dirname:/= %"
set "dirname=%dirname:?=&%"
set dirname
pause
exit
Note the exit at the end; that is necessary so that cmd.exe doesn't try to run bar when it reaches the end of the script. Otherwise, if the part of the directory name after the & happens to be a valid command, it could cause trouble.
NB: I'm not sure how robust this script is.
I've tested it with the most obvious combinations, but YMMV. [It might be more sensible to use delayed expansion exclusively, I'm not sure. It doesn't seem to be necessary except in the first set command. Jeb's answer here might be a better choice if you're going this route.]
For the curious, the script works like this:
Load the original command line into dirname [necessary for the reason pointed out by jeb]
Replace all the & characters with ?
Replace all the quote marks with *
If a quote mark is followed by a space, suppress the space.
NB: it is necessary to suppress the space to deal with both the case where the path contains a space (in which case Explorer adds quote marks around it) and the case where it doesn't.
Replace all remaining spaces with /
NB: ? * and / are illegal in file names, so these replacements are safe.
At this point the string looks like this:
C:\Windows\system32\cmd.exe//c/**C:\path\test.bat**C:\path\foo?bar**
So we just need to pull out the third asterisk-delimited element, turn any forward slashes back into spaces and any question marks back into ampersands, and we're done. Phew!

Split the passed parameter, then access all elements

My .bat file is supposed to execute command passed as the first argument, %1, which takes a list of parameters that are contained within the second parameter passed, %2.
Note that the second file is interpreted as a sentence, but is in fact a list of words. Therefore, program %1 complains as it has access to only one element. How can I split the second argument, %2, and invoke the correct format %1 %firstArgOf1 %secondArgOf1 ...
I am interested in solutions where the number of words in %2 is know in advance, but a variant with an unknown number of words in %2 is welcome.
EXAMPLE:
Program "myProgram" accepts 6 parameters. Any other number of parameters passed results in an error:
myProgram "this is one sentence passed as a single parameter"
However, myProgram works correctly in the following:
myProgram this is one sentence passed as a single parameter
The thing is, parameter "this is one sentence passed as a single parameter" is passed a a string (and this is fixed), so I have to find a workaround in a .bat file to split this argument.
#ECHO OFF
SETLOCAL
SET "parm1=%~1"
SET "parmrest=%*"
CALL SET "parmrest=%%parmrest:*%~1=%%"
ECHO(command is "%parm1%" with arguments "%parmrest%"
GOTO :EOF
This should accomplish your partition.
To remove quotes from a parameter, you can use the syntax %~1.
In a batch file it looks like
#echo off
myProg.exe %~1

Passing argument containing dot to a batch script

So I'm having trouble passing an argument with a period to a batch script file.
./myScript.bat 23.97
In my script, if I do
arg1 = %1
echo %arg1%
This will display 23.97 but if I do a comparison
arg1 = %1
if "%arg1%" == "23.97"
echo %arg1%
then it doesn't display at the argument at all. Fyi, i'm not trying to treat it at a float number, just a normal string. I'm no sure why it doesn't work, any help is appreciated. Thank you.
You can, in fact, have a dot (.) passed to a batch file as an argument. The section of your code that is causing you issue is the syntax that you use when setting the variable and using the if statement.
The correct syntax for setting a variable , as described by executing help set on the command line, is
Displays, sets, or removes cmd.exe environment variables.
SET [variable=[string]]
variable Specifies the environment-variable name.
string Specifies a series of characters to assign to the variable.
With this in mind, the correct way to set arg1 to the first argument passed to your batch file is
set arg1=%1
Your issue with the if statement is that you are trying to add a new line after the Boolean expression and before the next statement. The correct syntax is described by help if as
Performs conditional processing in batch programs.
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
Your if statement could be reveised to read like this:
if "%arg1%"=="29.37" echo arg1

Batch - set argument as variable without resolving eventual variable inside argument

I am trying to find a way to issue I have faced with my script. I have simulated my issue in short script so no long code will have to be read.
Basically what I want/need to achieve is to start my batch with argument and work with argument the same way as-is defined by script user, but replace percent signs with escape character followed by percent sign (% > ^%). But issue come up if argument contain some existing variable like %date%
Here is the short version of my code:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set "x=%~1"
set "y=!x:%%=^^%%!"
echo %y%
Argument can contain anything, but can also look as follow:
script.bat "this should be just plain text - %date%"
My expected output from the batch script would be like:
this should be just plain text - ^%date^%
However it seems that variable is resolved immediately and though percent signs are not even being escaped, since it can't find any. If argument does not contain any variable it works well, but this way output look like this:
this should be just text - Wed 01/15/2014
I am trying to avoid any additional scripting language usage (like VBS) and usage of any other application, but rather will have VBS way e.g. than nothing.
Any help, assistance or hint how to achieve this would be very appreciated.
The %date% variable is being expanded as soon as you call script.bat - so in your script %1 will already have the expanded %date% variable. You have to add the carets when calling the script -
script.bat "this should be just plain text - ^%date^%"

Resources