using set variable in copy command - windows

How can I copy a file inside a bat file using a set variable.
[run.bat]
set MY_WORKSPACE=workspace1.0.1
copy /Y /V D:\%MY_WORKSPACE%\webapp\target\app-generic.war C:\Opt\jboss-4.2.3.GA\server\default\deploy\
In above example, %MY_WORKSPACE% is invalid, however I can see the value by using 'echo'

Is that the whole batch file you're showing us?
I have a vague feeling you're doing the set and copy inside an if or similar statement with a block, e.g.
if foo==bar (
set MY_WORKSPACE=workspace1.0.1
copy ...
)
In this case you need delayed expansion for the variable change to take effect because the block in parentheses is parsed as a single command and all variables are substituted at parse time, not when runnin a command. Therefore %MY_WORKSPACE% will be empty once the block runs.
You can solve this by using
setlocal enabledelayedexpansion
at the top of your batch file and using !MY_WORKSPACE! instead of %MY_WORKSPACE% which will expand the variable just prior to running the command, not while parsing.

Try this way:
set MY_WORKSPACE="workspace1.0.1"

Related

Splitting file path in batch using for loop and variable substitution

I have searched around for quite a while without any luck in getting my script working. I feel like I'm pretty close, but need a little help. I am attempting to use a FOR loop to recursively scan "srcdir" (set at the beginning of my script), then once the loop returns files/paths (%%f), then I can substitute part of the file path with something else (eg; C:\rootpath\src for C:\rootpath\des).
I am able to do something just like this by using a script like this one:
set subdir=C:\rootpath\src
set subdir=%subdir:src=des%
echo %subdir%
However, what makes this difficult is that the root path of my "srcdir" may change (eg; C:\roothpath) and everything recursively after the "srcdir" may change (eg. anything after folder "src" in C:\rootpath\src). The only constant paths the folder src and the folder des (located in the same directory where I am running my batch file from).
So, by using the same technique in the previous example, I want to use a FOR loop to recursively find the full path of the files in "srcdir" (%%f) and substitute the folder "src" with the folder "des" in the path string. Therefore, I am trying to set "%%f" as a variable (subdir) and replace the folders using variable substitution.
Here is my current non-working script:
set srcdir=C:\rootpath\src
for /r "%srcdir%" %%f in (*.txt) do (
set subdir=%%f
set subdir=%subdir:src=des%
echo %subdir%
)
Any help would be greatly appreciated! Thanks!
You need to enable delayed expansion since you are assigning and reading variables within a block of code like a for loop:
setlocal EnableDelayedExpansion
set "srcdir=C:\rootpath\src"
for /R "%srcdir%" %%F in ("*.txt") do (
set "subdir=%%~fF"
set "subdir=!subdir:\src\=\des\!"
echo(!subdir!
)
endlocal
The setlocal EnableDelayedExpansion command enables delayed expansion; it also localises the environment, meaning that changes to environment variables are available only before endlocal is executed or the batch file is terminated.
To actually use delayed expansion, you need to replace the percent signs by exclamation marks, so %subdir% becomes !subdir!.

Windows prompt content variable as variable name

It is possible in windows command line refer to a content variable like a pointer?
Example:
SET envTEST=FOO
SET envPROD=BAR
SET CURR=envTEST
SET data=%%CURR%%
I want to data contains FOO but it contains %envTEST%
Thanks
You need multiple rounds of expansion. See How does the Windows Command Interpreter (CMD.EXE) parse scripts? for an explanation as to why the following work:
From the command line:
call set "data=%%CURR%%"
Or if delayed expansion has been enabled by cmd /v:on, then:
set "data=!%CURR%!"
From within a batch script:
call set "data=%%%CURR%%%
or
setlocal enableDelayedExpansion
...
set "data=!%CUR%!
If CURR is set and expanded within the same code block (typically done within IF or FOR loop), then:
setlocal enableDelayedExpansion
...
(
set "CURR=envTEST"
for %%V in (!CURR!) do set "data=!%%V!"
)
The CALL technique is quite slow, so I try to avoid it. It is not an issue for a single use, but it can become a major problem (slow performance) if used within a tight loop.

Windows Batch setting PATH through loop

I'm trying to create a drive with a suite of programs that can be implemented through the command prompt.
My issue is setting the PATH environment variable to include paths to the program suite. Since there are a couple directories for these suites (and I'm constantly adding more), I am trying to get it so I can have a .ini file be parsed through a simple Batch script and returned. From this I want to take the path parsed from the .ini file and append it to my current PATH variable.
This is the current script I'm trying to get fixed.
FOR /F "delims=" %%i IN ('call %cd:~0,3%\initTermPort\parse.ini.bat %cd:~0,3%\initTermPort\config.ini Alternate _path') DO (
SET PATH="%PATH%;%cd:~0,3%%%i"
)
The call to parse.ini.bat is getting the next path in config.ini on every run.
For example:
If I substitute SET PATH="%PATH%;%cd:~0,3%%%i" with ECHO %%i I get the following output:
E:\> (ECHO ~\bin)
~\bin
E:\>(ECHO ~\library\bin)
~\library\bin
But for some reason SET PATH="%PATH%;%cd:~0,3%%%i" is not setting the PATH at all.
Any help is appreciated.
The problem is that when the for code block (the code enclosed in parenthesis) was parsed, all the read operations to variables were replaced with the value in the variable before starting to execute, and in each iteration what is used is this initial value, and not the value inside the variable during the execution.
If you change a variable inside a block of code and need to access the changed value inside the same block of code, you need to enable delayed expansion and change the syntax to access the variables to use !varName! instead of %varName%. This indicates to the parser that this read operation must be delayed.
setlocal enableextensions enabledelayedexpansion
....
FOR /F "delims=" %%i IN (
'call %cd:~0,3%\initTermPort\parse.ini.bat %cd:~0,3%\initTermPort\config.ini Alternate _path'
) DO (
SET "PATH=!PATH!;%cd:~0,3%%%i"
)

How to persistently add directories to PATH when using SETLOCAL? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Make an environment variable survive ENDLOCAL
How to keep the value of a variable outside a Windows batch script which uses “delayed expansion local” mode?
I have a batch file that goes something like this:
REM I need to use SETLOCAL so as not to pollute the environment
REM with any variables used to implement the logic in this script
SETLOCAL
SET I_DONT_WANT_THIS_VARIABLE_TO_LEAK_OUTSIDE=c:\
REM BUT, there is this one change to the environment I want to make sticky:
PATH %PATH%;%I_DONT_WANT_THIS_VARIABLE_TO_LEAK_OUTSIDE%
The script uses SETLOCAL to isolate the environment from whatever the batch file wants to do, but this causes a problem: at the end I do want to modify the caller's environment in some very specific manner, but SETLOCAL prevents this (the change is undone as soon as the batch file exits). I also cannot call ENDLOCAL before setting the path because that restores the environment to its original state, wiping out the value of the variable so I cannot append its value to the path.
Is there a way to set the path while ignoring the SETLOCAL in effect? Alternatively, is there any trick to explicitly preserve the value of a variable from being wiped out when calling ENDLOCAL?
I am aware that it's possible to use a temp file as a vessel that can bypass the ENDLOCAL barrier, but a more elegant solution would be welcome.
Add this to the end of your script (or just before you return):
endlocal & #set path=%path%
The reason that this works is that the cmd parser performs environment variable expansion to the entire line before executing any of it. So by the time endlocal executes, the line that cmd is processing looks like:
endlocal & #set path=c:\whatever\the;c:\new\path;c:\is
Then endlocal throws away all the local changes, but the ones made to the path have been temporarily preserved in the set command that's about to be executed.

Setting a variable from an executable

I am running an executable in a batch file with two parameters;
cmd /k ""executable" "param1" "param2""
This returns a string that I want to launch. I can't figure out how to set this return in a variable and subsequently launch it in IE.
Any ideas?
If the returned string contains a single line you may use FOR /F to set the value of an environment variable. For example:
s1.cmd
echo this is a one line string
s2.cmd
#SETLOCAL
#ECHO OFF
for /f "tokens=*" %%a in ('cmd /c s1.cmd') do set MY_VAR=%%a
echo got: %MY_VAR%
ENDLOCAL
Result
C:\> s2.cmd
got: this is a one line string
C:\>
You can use the following syntax to capture the output of your executable into a variable:
FOR /F "tokens=*" %%i in ('%~dp0YOUR_APP.exe') do SET TOOLOUTPUT=%%i
Source
then you can pass the value on to IE like so:
START "YOUR_WINDOW_NAME" /MAX /D"C:\Program Files\Internet Explorer\" iexplore %TOOLOUTPUT%
I take it that the application code that determines the url is too complicated to be reproduced in a batch file directly, or the source to the executable has been lost. If not I personally would prefer to have the logic visible in the batch file itself.
start %1 %2
Edit: Romulo A. Ceccon posted a much better solution which doesn't involve any file system access and dirty tricks. Left this here for reference (it works with command.com as well if you need 9x compatibility), but please prefer Romulo's solution.
Go through an environment variable you set by using an intermediate helper script you dynamically generate from a template. You will need write permissions somewhere, otherwise it cannot be done (the Windows command shell language is very, very limited.)
Let's call your helper script template helper.tpl with the following contents:
set INTERMEDVAR=
Make sure that helper.tpl has only a single line (no trailing CRLF!) and make sure you don't have any spaces after the equals sign there.
Now, in your main script, capture the output from your command into a temporary file (let's call it my_output_file.tmp):
cmd /k ""executable" "param1" "param2"" > my_output_file.tmp
Then copy the contents of the helper template and the output together into your helper script, let's call it my_helper_script.cmd:
copy /b helper.tpl + my_output_file.tmp my_helper_script.cmd
Then evaluate the helper script in the current context:
call my_helper_script.cmd
Now the INTERMEDVAR variable is set to the first line of the output from "executable" (if it outputs more than one line, you're on your own...) You can now invoke IE:
start iexplore.exe "%INTERMEDVAR%"
And don't forget to clean up the created files:
del /q /f my_output_file.tmp my_helper_script.cmd
This will obviously not work when invoked multiple times in parallel - you'll have to parametrize the temporary file and helper script names using the current cmd.exe's PID (for example) so that they won't overwrite each other's output, but the principle is the same.
However, if you can get a real shell, use that. cmd.exe is extremely cumbersome.

Resources