run a input parameter as command in dos batch script? - batch-file

How can I run a command in my dos script from an input argument ?
Simplified script bla.bat:
CALL %1
Call it:
bla.bat "echo 'hello'" (or bla.bat "git status")
Error:
'"git status"' is not recognized as an internal or external command,
operable program or batch file.
It works if I do "CALL git status".

The important thing to remember is that the expanded text must look exactly like it would if you were to simply key in the command from the command line. (actually there are a few exceptions, but this is a good starting point).
To debug your script, simply put an echo before your call: #echo call %1. Now try running as you did earlier: blah.bat "echo 'hello'" produces call "echo 'hello'". Try running that from the command line - it doesn't work. You want call echo 'hello'.
One fix would be to change your script slightly: The ~ modifier strips enclosing quotes from the argument
#echo off
call %~1
Or you might be able to ditch the call and simply use the following (as long as you are not calling another batch file from which you want to return)
#echo off
%~1
If there are no other arguments on the command line, you might be better off using %* which expands to all the arguments
#echo off
%*
REM or call %*
Now you can call your batch like so
blah.bat echo "hello"
Be aware that batch has all kinds of special case weirdness that will likely require extra or different coding to work around. Too many to list - just expect the unexpected.

It looks like the problem may be that you have surrounding quotes in your input, which you'll need to stop it being broken into the different %n arguments, but try:
%~1 Which will strip any surrounding quotes from the input.
%~$PATH:1 which will strip any surrounding quotes then search within the $PATH env-var for the first match, then expand the string to include the full path to the command, which won't work for git using the windows distro because git is a batch file, and cmd would look for git status.bat
If its to be used with git, you may as well use %~1 and %~2 to call git then provide the argument to the git batch file, or call git.exe directly by modifying your $PATH. But remember that git.bat does some enviroment setup of its own before calling git itself.

I think you'll need %1% to echo the parameters. Here's my lame script which I think does what you want, works with your echo test:
bla echo hello
Gives:
C:\tmp>echo bla
bla
C:\tmp>echo echo
echo
C:\tmp>CALL echo hello
hello
echo %0%
echo %1%
CALL %*
If you want to parse through the command line arguments, let me know.

The problem is the spaces between the parameters are throwing you off (which is why you were using the quotes around git status).
Modify your bla.bat to iterate through your command line paremeters. This works for me:
SETLOCAL ENABLEDELAYEDEXPANSION
SET VAR1=
FOR %%A IN (%*) DO (
SET VAR1=!VAR1! %%A
)
call %VAR1%
ENDLOCAL
Then, run your bla.bat without the quotes around git status.
bla git status
Essentially, what this does is iterate through your command line parameters, and then executes them all as one command. The challenge comes from FOR loops in DOS not allowing you to use a variable that you're setting within itself, so you need to enable "delayed expansion" of variables. Then, the variable that you're setting needs to be encapsulated in exclamation points (not %'s). And of course, the space between !VAR1! and %%A keeps the parameters from running together in the CALL.

Related

Create a bat file with variables from another bat file

I want to create a bat file with set variables from another bat file.
This is for a startup .bat file that maps network drives and copies some files to the local computer and looks at the system services that needs to run.
It also needs to create a log file every time the logon .bat file runs. Here is a sample what I have done.
ECHO set SERVER IP=>>"V:\GENESIS\GENESIS INSTALL FILES\GenesisLogonUser.bat"
ECHO set DRIVE1=V>>"V:\GENESIS\GENESIS INSTALL FILES\GenesisLogonUser.bat"
ECHO set MAPDRIVE1=\\%SERVER IP%\v /P:Yes>>"V:\GENESIS\GENESIS INSTALL FILES\GenesisLogonUser.bat"
ECHO net use %DRIVE1%: %MAPDRIVE1% >>"%userprofile%\Documents\scripts\logonlog.txt">>"V:\GENESIS\GENESIS INSTALL FILES\GenesisLogonUser.bat"
You need to escape percent expansion of the variables. This can be done by doubling each % sign in a batch script:
set "VAR=Value"
echo %%VAR%%
This will echo:
%VAR%
Note that this does not work directly in the console window; you need to do it like this instead:
>set "VAR=Value"
>echo ^%VAR^%
%VAR%
So to apply this to your script, it looks like this (I excluded %USERPROFILE% from the escaping as I do not know how you like it; of course you could write %%USERPROFILE%% instead as well):
(
ECHO set "SERVER IP="
ECHO set "DRIVE1=V"
ECHO set "MAPDRIVE1=\\%%SERVER IP%%\v /P:Yes"
ECHO net use %%DRIVE1%%: %%MAPDRIVE1%%^>^>"%USERPROFILE%\Documents\scripts\logonlog.txt"
) > "V:\GENESIS\GENESIS INSTALL FILES\GenesisLogonUser.bat"
Since there is some redirection in the echoed text, this needs to be escaped like ^>^>.
I also put all ECHO commands within parentheses, which requires a single redirection operation only; this improves legibility and performance.
In addition, I improved the set syntax so that the entire assignment expression is placed in between a pair of quotation marks, which make it robust against special characters (the quotes do not become part of the value).

CMD BATs and Capture of Environment vars

I have a scripting system driven by powershell which calls BAT files
I want to record the Envs at the end of the BAT session so that they are available for the next BAT file. I have found what I did, did not capture changes from the BAT file...
More
I had code like
& cmd.exe "/c $script $optionalArgs & (echo Name^=Value&SET) > ""c:\path\end_envs.csv"""
$script == dosomework.bat
which appeared to work, i.e. the csv file is created with env's BUT does not have the ones created by $script... Rather seem to be the ENVs of the initial cmd.exe call...
After adding the 'echo xx' lines to a BAT file and calling this at the bottom of the bat file referenced in $script, all is OK, I see the env at the end of the $script BAT file
Is there a way to fool a cmd.exe /c to consider my extra echo info as part of the called script ?
Thanks
OR...
sae this as $$script.bat
#ECHO OFF
(
echo Name=Value
CALL $script %*
SET
)>"c:\path\end_envs.csv"
and modify your code to like
& cmd.exe "/c $$script $optionalArgs"
whee $$script.bat may naturally be any name you like.
Note that this assumes that $script.bat (the one you are actually executing) does not contain a setlocal instruction.
If $script is variable, then in the batchfile $$script.bat try
#ECHO OFF
SETLOCAL
(
echo Name=Value
set "params=%* "
CALL %1 %%params:* =%%
set "params="
SET
)>"u:\envs.csv"
GOTO :EOF
This assumes there are no confounding factors (parameters containing characters to which cmd is sensitive, for instance - normal alphameric strings should be fine)
So
write out the header line
set params to the supplied parameter list + a space
execute a subroutine firstparameter with parameter(s) remainingparameters. The call ...%%params:* =%% syntax means "the value of params, up to and including the first space"
clear params
list the remining environment variables.
The destination filename is of course up to you. I used a name that's convenient for my system.
So - you would call this script with a parameter of (the first name of the script you want to run) + (any other parameters you require)
Simplest would probably be to add
(echo Name^=Value
SET) > "c:\path\end_envs.csv"
to the end of $script (or at least, force those two lines to be executed just prior to exit)

how to add switches to commands in cmd

hey guys very simple question, I need to know how to add an extension/switch into a command in cmd.
Also how would I do this to a command that I made? (batch file that is called when typed the name of)
Ex.
Traditional
ipconfig /all
Modifed
ipconfig -a
or
ipconfig /a
This is a simple example to go with the answer above.
#echo off
if /i "%~1"=="-a" ipconfig /all
if /i "%~1"=="/a" ipconfig /all
(don't call your batch file ipconfig.bat - never use system command names for a batch file):
Cmd.exe provides the batch parameter expansion variables %0 through
%9. When you use batch parameters in a batch file, %0 is replaced by
the batch file name, and %1 through %9 are replaced by the
corresponding arguments that you type at the command line. To access
arguments beyond %9, you need to use the shift command. For more
information about the shift command, see Shift The %* batch parameter
is a wildcard reference to all the arguments, not including %0, that
are passed to the batch file.
For example, to copy the contents from Folder1 to Folder2, where %1 is
replaced by the value Folder1 and %2 is replaced by the value Folder2,
type the following in a batch file called Mybatch.bat:
xcopy %1\*.* %2
To run the file, type:
mybatch.bat C:\folder1 D:\folder2
Copied from MSDN
create a batch file mytest.cmd with notepad and add the following
rem start parsing out first parameter indicated with %1
set parm1=%1
set arg1=%parm1:~2%
if "%arg1%"=="a" echo A was the parameter
now arg1 will hold a from your example without the - or /
if you run mytest -a you'll see A was the parameter
if you run mytest -b you won't see a thing...
(as a matter of fact you see every single comand that is in the cmd file which is handy for debugging, try adding #echo off at the first line of mytest.cmd to get rid of the noise)
try at the cmd prompt set /?, if /?, for /? or call /? to learn more about the commands available.

updating command line parameters in batch file

**Batch file **I am writing batch file that takes in command line parameters and do some stuff if the parameters match. But when the run the batch file again with the new parameters, the file still runs with the old parameters.
first run : file.bat -name hello -w 400 -r 320
second run : file.bat -name hello -w 400.
When i do the second run of the file, it still performs the first run, i mean to say it still considers the parameters from the first run. Does anybody know why this is the case?
Thanks in advance.
Sorry for not posting the batch file code.
below mentioned is the code.
set filename=
set rate=
set hidden=
set rate=
:recheck
if "%1"=="-help" goto :help
if "%1"=="-name" goto :filename
if "%1"=="-h" goto :hidden
if "%1"=="-w" goto :weight
if "%1"=="-r" goto :rate
if "%~1"=="" goto :endofcommandline
:filename
shift
set filename =%1
shift
goto :recheck
For the other part of the file, I use the variable "filename" to do other stuff. I also use setlocal and endlocal at the beginning and the end of the file.
I have other corresponding labels for the each if statement and set different variables to the values passed to them if any by the user.
Sometimes, I also get echo is off when I try to print out the value of some variable.
All the variables which I use are cleared in the beginning of the file as mentioned above.
There are a couple points here.
"I also use setlocal and endlocal at the beginning and the end of the file."
"All the variables which I use are cleared in the beginning of the file as mentioned above."
Setlocal command does NOT clear the variables, it preserve current variables from posterior modification. This mean that if in a previous execution of your Batch file, or even via typed SET commands, filename variable was defined, it value remains until it is deleted or modified.
"Ok!", you said, "filename variable is modified the second time the Batch file run, Right?"
Well, no... The following line:
set filename =%1
does NOT modify "filename" variable, but "filename " instead (filename and a space). Try this:
set filename=No space
echo %filename%
set filename =Bad name with trailing space
echo %filename %
echo %filename%
You must carefully check your program to avoid this type of errors.

Batch file shows batch commands

I got a batchfile with a length of 4776 lines. Now i want the batchfile to show the commands and text from the batchfile itself I've written.
Anticipated thanks
VVW
I like adding this at the beginning of my batch scripts:
#ECHO OFF
IF /i {%1}=={ECHO} ECHO ON&SHIFT
This checks if the first argument is "ECHO" (case-insensitive). If it is, it turns ECHO ON, and then shifts the arguments such that %2 becomes %1, %3 becomes %2.
This way the script can behave as though you ran it normally, but with ECHO ON.
Remove the below line from the batch file.
#echo off
Or make it on by doing
#echo on
Try putting your code in a variable, then print it.
mycode = %Code Code Code%
echo %mycode%
Try putting this ain your batch file.
#type %0
Maybe I am misunderstanding things but it seems like everyone is misunderstanding where the "#" symbol is necessary. If you have this:
#echo off
Then you run commands like this:
#call mycommand.bat
But, if you have this at the top of your file:
echo off
Then, your commands are silenced like so:
call mycommand.bat
You could just open the command line and type this
type yourbatchfilename.bat >> code.txt
This would write your whole thing again in a txt file

Resources