Batch file Scipt Executing all instructions in one go in if statement - batch-file

Im new to batch script and trying to create a script which is going to help me setup a long manual process in a go. i have used if else statement in the batch script but all instructions are executed in one go i have only given 1 as input. code is mentioned below.
call echo 1. Clone a branch from bitbucket
call echo 2. Specify the Absolute path of project
set /P choice=" Enter your Choice : "
if %choice%==1 (
call set /P fo="enter folder name: "
call cd %USERPROFILE%\Desktop\ProjectFolder\%fo%
echo Clone will be created in the following address
call cd
call set /P gitUserName="Enter bitbucket UserName : "
call set /P branch=" Enter Branch Name : "
call echo Git User : %gitUserName%
call echo Branch Name : %branch%
call git clone https://%gitUserName%#bitbucket.org/MyProject/Project-demo.git -b %branch%
call cd Project-demo
) else (
call set /P pathname = "Enter Absolute path of Project-demo : "
cd %pathname%
)
im running it on windows 10. tried disabling #echo off for debugging purposes and found that all instructions are getting executed and at last {call set /P fo="enter folder name: " } <-- this line is executed.
i want it to create a folder and git clone one of my project here. Any Help greatly appreciated.
Also do tell me is call necessary wherever i used it.

The problem you are having has to do with delayed expansion. Everything inside of your parens is processed at once so you can't really do what you are trying to do without more complication. This has to do with Delayed Expansion .
You have two choices.. you can either:
enable EnableDelayedExpansion flag and use "!" instead of "%" within your blocks..
OR
Use "call" properly.. unlike your current use. Call is for calling a label within a batch file.. sort of like a function. If you use goto :EOF at the end of that label.. it will return to the caller like a function in a real programming language.
BTW.. call can also be used to call another batch file but we won't talk about that right now. One bit at a time..
I will show you the call method (which I prefer and other people hate). The call method was the only way to do this before the EnableDelayedExpansion keyword was added.
:)
`
#echo off
:START
cls
echo 1. Clone a branch from bitbucket
echo 2. Specify the Absolute path of project
set /P choice=" Enter your Choice : "
:: If they didn't pick a valid option, show the question again...
if not "%choice%"=="1" if not "%choice%"=="2" goto :START
:: Otherwise, take them down the right path
if "%choice%"=="1" call :DoBitBucketClone
if "%choice%"=="2" call :DoAbsolutePath
:: goto :EOF here will simply exit the script
goto :EOF
:DoBitBucketClone
set /P fo="enter folder name: "
cd %USERPROFILE%\Desktop\ProjectFolder\%fo%
echo Clone will be created in the following address
cd
set /P gitUserName="Enter bitbucket UserName : "
set /P branch=" Enter Branch Name : "
echo Git User : %gitUserName%
echo Branch Name : %branch%
git clone https://%gitUserName%#bitbucket.org/MyProject/Project-demo.git -b %branch%
cd Project-demo
:: we 'could' just exit here but I am trying to
:: show you how the return works..
goto :EOF
:DoAbsolutePath
set /P pathname="Enter Absolute path of Project-demo : "
echo "Path set to %pathname%"
cd /d %pathname%
:: we 'could' just exit here but I am trying to
:: show you how the return works..
goto :EOF
`

When you remove #ECHO OFF it will show you the entire if statement, not just the part that you are running. That's just a limitation of batch scripting.
Also, you are attempting to use variables in the if statement that are also set inside the if statement. Due to the way that parsing and substitution is done, you need to either use Delayed Expansion (using !) or create a subroutine
Some other changes I made are:
Check that the target directory exists. If not, make it.
Explicitly check else case for 2 and add an error case for anything other than 1 or 2.
Wrap paths in quotes
Removed unnecessay usage of call
Added error check for git clone failure
The following illustrates a way you can do it with delayed expansion:
#ECHO OFF
SETLOCAL EnableDelayedExpansion
echo 1. Clone a branch from bitbucket
echo 2. Specify the Absolute path of project
set /P choice=" Enter your Choice : "
if %choice%==1 (
set /P fo="enter folder name: "
SET "DEST=!USERPROFILE!\Desktop\ProjectFolder\!fo!"
IF NOT EXIST "!DEST!" mkdir "!DEST!"
cd "!DEST!"
echo Clone will be created in the following address
echo !DEST!
set /P gitUserName="Enter bitbucket UserName : "
set /P branch=" Enter Branch Name : "
echo Git User : !gitUserName!
echo Branch Name : !branch!
git clone https://!gitUserName!#bitbucket.org/MyProject/Project-demo.git -b !branch!
if errorlevel 1 EXIT /B 1
cd Project-demo
) else if %choice%==2 (
set /P pathname = "Enter Absolute path of Project-demo : "
cd !pathname!
) else (
ECHO:
ECHO ERROR: Unexpected choice '%choice%'
ECHO:
)
(ENDLOCAL
EXIT /B 0)

Related

How to execute a program in set variable?

I'm writing the universal batch script for a Git upload.
I want to specify the location of the Git executable, if user doesn't provide one/is not located by where command.
C:\>#echo off
set Windows=C:\Windows\System32
set where=%Windows%\where.exe
: --- Git location ---
set "Git=..." Executable
if %Git%==... (
set "Git=%where% git.exe" : <---
)
echo %Git%
where git.exe
%Git%
C:\Program Files (x86)\Git\cmd\git.exe
The problem is, that executing a variable is different than echoing it.
How can I make echo %Git% output C:\Program Files (x86)\Git\cmd\git.exe?
If you simply wanted to request from the end user the absolute path of the git executable, if it was not located in %Path%, then perhaps something like this may suit your purposes better:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For %%G In ("git.exe") Do Set "Git=%%~$Path:G"
If Defined Git GoTo Main
Set /P "Git=Enter the absolute path of your chosen git executable>" || GoTo :EOF
For %%G In ("%Git:"=%") Do If /I "%%~nxG" == "git.exe" If "%%~aG" Lss "d" If "%%~aG" GEq "-" GoTo Main
GoTo :EOF
:Main
Echo The absolute path to your primary git executable is %Git%.&Pause
The last line is for demonstation only, you would obviously change that to:
"%Git%" [Args]
or:
Start "" "%Git%" [Args]
As an alternative, if you really wanted to use where.exe, which would give you the additional benefit of checking the current directory, as well as %Path%, but could grab the location of more than one matching file, just replace line 3 of the script above with:
Set "Git=" & For /F Delims^= %%G In ('%__AppDir__%where.exe "git.exe" 2^>NUL') Do If Not Defined Git Set "Git=%%~G"
Or:
Set "Git=" & For /F Delims^= %%G In ('%SystemRoot%\System32\where.exe "git.exe" 2^>NUL') Do If Not Defined Git Set "Git=%%~G"
In the case of multiple found files, this would define the variable with that which would be invoked by default should you have simply entered git.exe within that same environment.

CMD: doesn't recognize the path

i have created a simple batch, that should get the value from the input, and act according to the choice:
set CA="C:\A\"
set CB="C:\B\"
set SRV="server\"
set /p choice=Insert choice (A/B):
if %choice%== A cd /d %CA%%SRV% & start "" "batch.bat"
if %choice%== B cd /d %CB%%SRV% & start "" "batch.bat"
In the script the first choice works as expected, whereas the second one throws: "The system cannot find the path specified".
The path is correct and the file is there. Directly from CMD the single command works fine. What am i doing wrong in the script?
Sticking with your structure, would the following work for you?
#Echo Off
Set "CA=C:\A\"
Set "CB=C:\B\"
Set "SRV=server\"
Set /P "choice=Insert choice (A/B): "
If /I "%choice%"=="A" If Exist "%CA%%SRV%batch.bat" Start "" /D"%CA%%SRV%" "batch.bat"
If /I "%choice%"=="B" If Exist "%CB%%SRV%batch.bat" Start "" /D"%CB%%SRV%" "batch.bat"
Pause

How do I make a bat do something else if executed with a flag/switch (Title is probably vague)

So, I've been working on a batch script that essentially helps you with youtube-dl, essentially filing out all the data it needs to download into a directory. I want to be able to make a special shortcut that launches it, and instead of doing what it normally does, I want it to go through a text file (for example, let's call it update list.txt) and update playlists when that shortcut is run. I don't want to make another batch file that does this (for simplicity for user).
Here's what I have so far:
#echo off
:loop
title Welcome to CCF_100's youtube-dl helper!
set /A loop=loop+1
echo.Times Looped: %loop%
cd %~dp0
set /p input=Enter YouTube ID, URL, or Playlist ID:
set /p Output_Dir=Enter Directory you want to save in (Directory will be
created if it does not exist):
set /p flags=Enter flags (Optional):
if exist %Output_Dir%\ (goto Do_the_thing) else (goto make_directory)
:make_directory
mkdir "%Output_Dir%"
if /I %loop% LEQ 2 goto Do_the_thing
explorer "%Output_Dir%"
:Do_the_thing
title CCF_100's ytdl helper: currently downloading: %input% to %Output_Dir%
youtube-dl.exe -i -U %flags% -o "%Output_Dir%\%%(title)s - %%(id)s.%%(ext)s"
%input%
set /p loop=Successfully downloaded file(s). Download more?
if /i %loop%==y goto loop
if /i %loop%==Y goto loop
if /i %loop%==n goto end
if /i %loop%==N goto end
:end
exit
And yes I know the last two if statements are unnecessary.
You can get the arguments of a batchfile by reading the value of %n with n being a number between 0 and 9 or an asterisk. 0 is the batch-file itself (in the sense of the path to it) and the asterisk means any additional argument (excluding the batch-file-path).
So with that you can check for the contents of %1 and see if it is the flag you thought of or existent at all:
REM Demo only!
#echo off
if "%1"=="" (
echo no flags set
) ELSE (
echo flag set: %1
)
or change the if in a similar fashion to react to your flag only.

Batch script to import Virtual Box appliance adding quotation marks to end of shared folder path

I have created a batch script that imports a virtual box appliance and configures it for that machine. Part of the script deletes the share (between the guest and host) and creates it again with a new host path like this:
"%vbPath%VBoxManage" sharedfolder remove "%devBoxName%" --name wwwshare
"%vbPath%VBoxManage" sharedfolder add "%devBoxName%" --name wwwshare --hostpath "%shareName%"
When I put these lines of code into a separate file and set shareName directly above, it works fine (eg. shareName=c:/test). However, when I run it as part of the script, the share that is created would have c:/test" as the share path, which of course means it fails.
This is all the code that is used for this variable:
setlocal enabledelayedexpansion
:: Check they want the default share folder name
SET shareName=C:\ld-sd%devNum%-rh7-www\
:getShareName
SET /P shareNameOK="Your shared folder will be %shareName%. Do you want to keep this value (enter y to keep and n to change): "
cls
if /I "%shareNameOK%"=="n" (
SET /P shareName="Please enter the path and name you would like for your shared folder: "
GOTO :getShareName
) else (
if /I not "%shareNameOK%"=="y" (
echo WARNING: You did not enter y or n
GOTO :getShareName
)
)
:getShareCheck
:: Check if this folder exists and if they plan to keep or overwrite it if it does
if /I exist "%shareName%" (
echo WARNING: Selecting yes will result in all website files being erased!
SET /P shareNameOverwrite="This folder already exists, would you like to overwrite the files in it with a clean copy (yes/no)? "
if /I not "!shareNameOverwrite!"=="no" (
if /I "!shareNameOverwrite!"=="yes" (
#RD /S /Q "!shareName!"
timeout /t 1 /nobreak > NUL
mkdir "!shareName!"
) else (
echo WARNING: You did not enter yes or no - NOTE full name
GOTO :getShareCheck
)
)
) else (
SET shareNameOverwrite=yes
mkdir "!shareName!"
)
Whenever I echo the variable (anywhere in the file) it shows no quotations in it. This is the only point it causes an issue. I have even echoed the entire line in question:
echo "%vbPath%VBoxManage" sharedfolder add "%devBoxName%" --name wwwshare --hostpath "%shareName%"
and it shows fine. Where are the quotation marks coming from?
The problem ended up being the line:
SET shareName=C:\ld-sd%devNum%-rh7-www\
should have been:
SET shareName=C:\ld-sd%devNum%-rh7-www
I had missed that there was a \ on the end.
The result of this is that with a \" it will take the " as part of the string and not the end of the string.
So if ever you have a rouge " at the end of a variable, make sure your variable does not end in a backslash!

Problems with BAT file: IF/ELSE not working as expected

I'm trying to make a short BAT file and I'm having trouble with one of its functions. I've tried a number of different ways to do this and none of them seem to work, but being a beginner at this I can't figure out the problem. Basically, the script, as it runs, is supposed to check if a certain .BAT file exists, and if it does, the script asks if the user wants to run it. If the user indicates Y, the other BAT is called and then the original script proceeds. If the user indicates N, the script is supposed to proceed without calling the other BAT. So far the script always notices and asks about the file, but choosing Y at the prompt never works. I'm sure the solution is obvious, but it's escaping me. Here's the code:
SET /P kmname=Enter database name:
:kmstart
IF EXIST C:\Visual\area\%kmname%\%kmname%.flt (
ECHO %kmname%.flt found, will now create %kmname%.ive.
CD C:\Visual\area\%kmname%\
IF EXIST Preprocess.bat (
SET /P kmpreproc=Found Preprocess.bat. Do you want to run it now?
IF /I "%kmpreproc%" EQU "Y" (
GOTO PREPROC
) ELSE (
GOTO CONTINUE
)
)
GOTO CONTINUE
) ELSE (
ECHO C:\Visual\area\%kmname%\%kmname%.flt does not exist. Try again.
SET /P kmname=Enter database name:
GOTO kmstart
)
:PREPROC
ECHO Running Preprocess.bat.
:CONTINUE
ECHO Continuing process.
PAUSE
The problem is your variables are being evaluated before they enter the if's, which means cmd won't see any changes until they have ended.
This is causing problems for you as your variables kmpreproc and, depending on the first if result, kmname change within the if blocks.
The fix (presuming the rest of your code is working) is to enable delayed expansion and use delayed expansion instead of normal expansion, by changing the %'s to ! on your variables.
setlocal enabledelayedexpansion
SET /P kmname=Enter database name:
:kmstart
IF EXIST C:\Visual\area\!kmname!\!kmname!.flt (
ECHO !kmname!.flt found, will now create !kmname!.ive.
CD C:\Visual\area\!kmname!\
IF EXIST Preprocess.bat (
SET /P kmpreproc=Found Preprocess.bat. Do you want to run it now?
IF /I "!kmpreproc!" EQU "Y" (
GOTO PREPROC
) ELSE (
GOTO CONTINUE
)
)
GOTO CONTINUE
) ELSE (
ECHO C:\Visual\area\!kmname!\!kmname!.flt does not exist. Try again.
SET /P kmname=Enter database name:
GOTO kmstart
)
:PREPROC
ECHO Running Preprocess.bat.
:CONTINUE
ECHO Continuing process.
PAUSE
Here is below my corrected and tided up code :
#echo off
SET /P kmname=Enter database name:
:kmstart
IF EXIST C:\Visual\area\%kmname%\%kmname%.flt (
ECHO %kmname%.flt found, will now create %kmname%.ive.
CD C:\Visual\area\%kmname%\
IF EXIST Preprocess.bat (
SET /P kmpreproc=Found Preprocess.bat. Do you want to run it now?
IF /I "%kmpreproc%"=="Y" (
GOTO PREPROC
)
GOTO CONTINUE
)
)
ECHO C:\Visual\area\%kmname%\%kmname%.flt does not exist. Try again.
SET /P kmname=Enter database name:
GOTO kmstart
:PREPROC
ECHO Running Preprocess.bat.
call "cmd /c start Preprocess.bat"
pause
:CONTINUE
ECHO Continuing process.
PAUSE
If it doesn't work try writting setlocal EnableDelayedExpansion under #echo off and replacing all % with ! .

Resources