Batch command mixing syntax during execution - batch-file

I have tried to add a variable into an already existing batch file that I have written. However, when using the new command with the variable the command gets jumbled up.
How it supposed to work.
A user is prompted for an input (one of 3 letters). The input dictates the root directory used for a software execution. This section of code pulls a list of .elf files and is supposed to write them to a .txt file in the root directory.
Issue.
When using the variable directory, the .txt file and directory are switched during execution.
Original (Works)
DIR \\somepath\%VAR%\*.elf /b /o-s>C:\MyRootFolder\unlk.txt
New command with 2nd variable (acts strangely)
DIR \\somepath\%VAR%\*.elf /b /o-s>%root%\unlk.txt
but executes like this!?
DIR \\somepath\25091562033-00\*.elf /b /o-s \unlk.txt 1>C:\MyRootFolder
I am trying to have my root folder selected by an input further up because there are 3 different versions of software that I need to use to perform an operation. Being able to have the folder selected by an input would make things a lot easier.
Any ideas of why this executes semi-backwards?
Edit:
Here is the first section of my batch file all the way down to where the error happens. I have removed some of the code that doesn't relate to the issue. Note that the excessive pauses are for troubleshooting and the section which sets the variable %ECUPN% has been removed as it is working as intended.
ECHO off
:Ask
CLS
ECHO What type of processor does this ECU have?
ECHO F = Freescale_Quasar
ECHO T = TI
ECHO M = Motorola
SET INPUT=
SET /P INPUT=[F/T/M]: %=%
IF /I "%INPUT%"=="F" SET root=C:\Freescale_Quasar && GOTO :Fetch
IF /I "%INPUT%"=="T" SET root=C:\TI_MK100 && GOTO :Fetch
IF /I "%INPUT%"=="M" SET root=C:\MK100_Motorola && GOTO :Fetch
GOTO :Ask
:Fetch
CLS
Echo on
ECHO Fetch
pause
DIR \\mofs01p2.auto.contiwan.com\didf5076\FlashDataFiles\Flashline\%ECUPN%\*.elf /b /o-s>%root%\unlk.txt
pause
SET /P Code=<%root%\unlk.txt
pause
COPY "\\mofs01p2.auto.contiwan.com\didf5076\FlashDataFiles\Flashline\%ECUPN%\%Code%" "%root%\unlock.elf" || GOTO :error_1
pause
ECHO App = %code%>>C:\Unlock\log.txt
pause
GOTO :Build_1

Related

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.

How to ask user of batch file for a folder name/path?

I was able to create this batch file to move certain files from one folder to another. But I want to be able to use it also on different folders. For instance here I'm only moving files from UTS16. I want to use this batch file also for other folders like UTS15, UTS14, UTS13, UTS12, etc.
What do I need to change in code to ask the batch user on which folder to run? What am I missing?
#echo off
SET /P letter=Please give your drive letter and press ENTER:
ECHO %letter%
PAUSE
SET Datefolder="%date:~10,4%_%date:~4,2%_%date:~7,2%_%time:~0,2%%time:~3,2%"
MD "%Datefolder%"
mkdir %letter%:\UTS16\Database\"RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.dbf" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.cdx" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.~cd" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.~db" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.fpt" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\RTBackup%Datefolder%\zipdata.dbf" "%letter%:\UTS16\Database\"
pause
start "" %letter%:\UTS16/dbrepair.exe
I suggest for your task following commented batch file:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
goto UserPrompt
rem Define environment variable BaseFolder with a double quote character as
rem value in case of the user enters nothing on prompt in which case the
rem variable BaseFolder is still defined with the double quote as value.
rem Then let the user enter the folder path or drag and drop
rem the folder over the console window to enter the path.
rem Next remove all double quotes from folder path and test
rem if the variable BaseFolder still exists with a value.
rem Last replace forward slashes by backslashes in case of user entered
rem the path with forward slashes, make sure the folder path does not
rem end with a backslash and test if the folder really exists in case of
rem user has made a typing mistake on entering manually the folder path.
rem Run the backup and repair operation if entered folder exists as expected.
:UserPrompt
cls
echo/
echo Please type the database base folder path and press ENTER.
echo/
echo Or alternatively drag ^& drop the folder from Windows
echo Explorer on this console window and press ENTER.
echo/
set "BaseFolder=""
set /P "BaseFolder=Path: "
set "BaseFolder=!BaseFolder:"=!"
if "!BaseFolder!" == "" goto UserPrompt
set "BaseFolder=!BaseFolder:/=\!"
if "!BaseFolder:~-1!" == "\" set "BaseFolder=!BaseFolder:~0,-1!"
if "!BaseFolder!" == "" goto UserPrompt
echo/
if not exist "!BaseFolder!\Database\*" (
echo There is no folder "!BaseFolder!\Database".
echo/
choice "Do you want to enter the path once again "
if errorlevel 2 goto ExitBatch
goto UserPrompt
)
set "BackupFolder=%BaseFolder%\Database\RTBackup%DATE:~10,4%_%DATE:~4,2%_%DATE:~7,2%_%TIME:~0,2%%TIME:~3,2%"
rem For German date/time format which is for DATE TIME: dd.mm.yyy hh:mm:ss,xx
rem set "BackupFolder=%BaseFolder%\Database\RTBackup%DATE:~-4%_%DATE:~-7,2%_%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%"
if exist "%BackupFolder%\*" goto MakeBackup
md "%BackupFolder%"
if errorlevel 1 (
echo/
echo Error: Failed to create backup folder !BackupFolder!
echo/
choice "Repair without making a backup "
if errorlevel 2 goto ExitBatch
goto RunRepair
)
:MakeBackup
echo Making a backup to folder !BackupFolder! ...
move /-y "%BaseFolder%\Database\*.dbf" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.cdx" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.~cd" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.~db" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.fpt" "%BackupFolder%" 2>nul
move /-y "%BackupFolder%\zipdata.dbf" "%BaseFolder%\Database\" 2>nul
:RunRepair
echo/
echo Running database repair ...
"%BaseFolder%\dbrepair.exe"
:ExitBatch
endlocal
Please read first answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? explaining the difference between set variable="value" and set "variable=value".
The environment variable Datefolder was created in batch file in question with double quotes included in environment variable value resulting in expanding
"%letter%:\UTS16\Database\RTBackup%Datefolder%"
for example to
"C:\UTS16\Database\RTBackup"2017_01_13_1250""
which of course is not good. Double quotes inside a double quoted string is in general not correct.
And the command line
mkdir %letter%:\UTS16\Database\"RTBackup%Datefolder%"
expanded for example to
mkdir C:\UTS16\Database\"RTBackup"2017_01_13_1250""
Error correction of Windows must do overtime to fix the folder paths.
The date/time format of the environment variables DATE and TIME depends on Windows region and language settings of current user. I needed a different line to define the backup folder with date and time in name for my German Windows machine. There are region independent solutions posted for example at How to get current datetime on Windows command line, in a suitable format for using in a filename? However, if the faster command line using the environment variable DATE and TIME work on the computers where this batch file is used, there is no need to replace that line with a region independent solution.
The batch file in this answer uses delayed expansion of environment variables mainly to prevent an exit of batch processing in case of user enters by mistake a path string which results without usage of delayed expansion in a syntax error.
The user can drag & drop the folder also for example from Windows Explorer over the console window to enter the folder path on prompt.
echo/ is used to output a blank line which is better than echo. as explained by DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/
The ampersand & is interpreted by Windows command interpreter as operator for executing multiple commands in one command line in an unquoted string. For that reason it is necessary to escape this character with the caret character ^ to be interpreted as literal character to echo into the console window. See Single line with multiple commands using Windows batch file for details on meaning of &, && and || in a command line in an unquoted string and not escaped with ^.
The command choice is used on asking if the user wants to proceed on error or exit the batch file. This command appends to prompt text in square brackets the keys to press for Yes or No in language of Windows and a question mark, i.e. [Y,N]? on English Windows or [J,N]? on German Windows. choice does not allow any other key before exiting. The exit code assigned to errorlevel is 2 on No and 1 on Yes.
The Microsoft support article Testing for a Specific Error Level in Batch Files explains the usage of if errorlevel to test on exit code of previous command or application. In this case it is enough to test on errorlevel being greater or equal 2 to exit batch processing on an error in case of user chooses No.
The batch file does not check if "%BaseFolder%\dbrepair.exe" really exists before it tries to execute this application. It would be good if that additional check with appropriate error message for the user is added, best before creating the backup folder.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
choice /?
cls /?
echo /?
endlocal /?
goto /?
if /?
md /?
move /?
set /?
setlocal /?
And read also the Microsoft TechNet article Using command redirection operators for an explanation of 2>nul.

Batch script to move to another section of the script if there is no input from user

I am trying to get this script to jump to another section of the script if there is no input from the user.
Down at the if %input%== area.
What I'm trying to do is skip to the section where the script checks for .mp4 files and moves them if they are there. Am I supposed to set a variable or loop for that section? Thanks for any replies
#echo off
echo Checking for youtube-dl updates.
pause
youtube-dl -U
rem Enter the url or urls that you want to download from
set /p input="Enter the url(s) you want to download:"
rem Uses the youtube-dl continue (-c) option to download multiple files if not in a playlist
youtube-dl -c "%input%"
rem pause
if %input%=="" GOTO:EOF
cls
echo Download complete, please wait while files are transfered to appropiate folder
pause
for %%o in (.mp4) do move "*%%o" "E:\Documents\scripts\videos\"
if not exist do echo .mp4 files are no longer in this directory
pause
How about following script? This script waits for 3 seconds while "file.mp4" doesn't exist. It keeps to wait until the file exists. About "filename", you can change for your script.
#echo off
set waittime=3
set filename=file.mp4
:loop
if not exist %filename% (
Timeout /t %waittime% /nobreak > nul
goto loop
)
echo Find %filename%
When doing string comparison in batch you have to make sure, that both parts are equal, which in your case will never happen! In most languages strings have double quotes around them. In batch they usually do not.
To solve your problem enclose %input% in double quotes as well.
Note that it can be useful to do something like "x%input%"=="x" to prevent certain characters like <>|to be at the beginning of the comparison string.
You can check this on your own with these few lines:
#echo off
set /p input="Input something or nothing here "
echo %input%
echo "%input%"
pause
If you are hitting Return without any input you will see that only the bottom one will output "" which is the string you are comparing to.

How to identify spacebar in a Batch Script?

So, I created a program, which can create and delete folders on the desktop. And I have a problem, when I just write a single space for the name I got the error "Please write a valid folder name!" so it works, but if I'm using more than one spaces, it says "Folder created successfully", and I want to make this program to make an error when I only using spaces in the folder's name. Please help!
Here's a part of my code (the full code is 132 lines long)
set Choice=
set /p Choice="Choose an option: "
if '"%Choice%"'=='"1"' goto masodik
if '"%Choice%"'=='"2"' goto negyedik
if '"%Choice%"'=='"3"' goto otodik
if '"%Choice%"'=='"4"' goto harmadik
if not '"%Choice%"'=='"1"' goto hiba2
if not '"%Choice%"'=='"2"' goto hiba2
if not '"%Choice%"'=='"3"' goto hiba2
if not '"%Choice%"'=='"4"' goto hiba2
:masodik
cls
echo Create a folder
echo ---------------
echo.
cd "%systemdrive%/documents and settings/%username%/desktop"
echo Enter the folder's name!
echo.
set /p mappaneve="The folder's name: "
if "%mappaneve%" EQU "" goto hiba
if EXIST "%mappaneve%" goto hiba3
md "%mappaneve%"
cls
echo Create a folder
echo ---------------
echo.
echo Successfully created "%mappaneve%"!
timeout /t 3 >nul
cls
goto elso
if "%mappaneve: =%" EQU "" goto hiba
ie, replace all spaces with nothing and if the result is nothing then the input must have been all spaces (if that was what you were asking)
quotes is used in variable asignation to make sure space are handle correctly. don't include quotes inside your variable unless when you want to use it.try change your code into this.
set /p "mappaneve=The folder's name: "
Magoo posted the right code in his short answer.
Here is a much longer answer with commented batch code and additional explanations on the various improvements in this code in comparison to code in question post.
set "UserChoice="
set /p "UserChoice=Choose an option: "
if "%UserChoice%" == "1" goto masodik
if "%UserChoice%" == "2" goto negyedik
if "%UserChoice%" == "3" goto otodik
if "%UserChoice%" == "4" goto harmadik
rem None of the 4 valid numbers was entered.
goto hiba2
:masodik
rem Set current directory to desktop directory of current user.
cd /D "%USERPROFILE%\Desktop"
cls
echo Create a folder
echo ---------------
echo.
rem Define a double quote as default value to be able to remove all
rem double qotes from input string with no syntax error even if the
rem user just hits key RETURN or ENTER without entering any string.
set "mappaneve=""
set /p "mappaneve=Enter folder name: "
rem Remove all double quotes from entered folder name.
set "mappaneve=%mappaneve:"=%"
rem Check if user has entered anything at all and if entered folder name
rem does not exist of only 1 or more spaces by using environment variable
rem substitution which removes for string comparison all spaces from the
rem entered folder name.
if "%mappaneve%" == "" goto hiba
if "%mappaneve: =%" == "" goto hiba
rem Appending \* makes sure to test on existence of a folder and not a file.
rem It does not matter if entered folder name ends already with a backslash.
rem Does the folder already exist?
if exist "%mappaneve%\*" goto hiba3
rem Create the folder and verify if that was successful with
rem saving error message into a temporary file for output below.
md "%mappaneve%" 2>"%TEMP%\%~n0_FolderError.tmp"
if errorlevel 1 goto FolderError
rem On successful creation of the folder an empty file is
rem created which should be removed before processing further.
del "%TEMP%\%~n0_FolderError.tmp"
cls
echo Create a folder
echo ---------------
echo.
echo Created successfully "%mappaneve%".
timeout /t 3 >nul
cls
goto elso
:FolderError
cls
echo Failed to create folder "%mappaneve%".
echo.
echo Error message:
echo.
type "%TEMP%\%~n0_FolderError.tmp"
del "%TEMP%\%~n0_FolderError.tmp"
echo.
pause
The improvements are:
Comparing strings with command IF should be done with using surrounding double quotes only. The single quotes are removed from the 4 string comparisons.
Of course if the batch user enters for example "2" (number 2 with double quotes) the batch execution would be exited by command processor because of a syntax error caused by processing if ""2"" == "1" goto masodik. Using delayed variable expansion would be one solution for this issue.
The 4 lines with if not '"%Choice%"'==... can be replaced simply by goto hiba2 as they are all definitely true after the first 4 string comparisons.
choice (SS64 article) is a standard Windows command. Therefore it is advisable to avoid choice (Microsoft article) as name for an environment variable or label. UserChoice (CamelCase spelling for easier reading) is used instead of Choice.
Command choice would be a very good alternative for first user prompt because then the user can't enter something different than 1, 2, 3, or 4.
There is predefined by Windows the environment variable USERPROFILE containing path to the user´s profile directory containing the directory Desktop and other user account related directories. This variable should be used instead of building path with other variables.
The directory separator on Windows is the backslash character and not the forward slash character. Windows supports in the meantime also directory paths with / instead of \, but it is nevertheless better to use the right directory separator.
The user´s profile directory can be on a different drive than system drive. Or the drive from which the batch file is executed is a different one than the drive of user´s profile directory. Therefore it is advisable to use command CD with parameter /D as otherwise changing directory could fail if current drive is different to drive of user´s profile directory.
It is advisable to define a default for an environment variable before prompting a user or clearing the variable. The user can hit just RETURN or ENTER in which case the environment variable keeps its value.
This was done for Choice, but was forgotten for mappaneve.
The user could enter a folder name with double quotes. Therefore it is advisable to remove all double quotes from entered folder name as otherwise the batch script processing would be exited by command processor because of a syntax error on further processing the batch file.
To really test existence of a folder with if exist and not also a file, it is necessary to append \* to the folder name as otherwise if exist could be true also with user input string is name of an existing file.
Creation of folder could fail because of 1 or more invalid characters in folder name, a file exists with same name already, or the user does not have permission to create a folder.
The last reason is very unlikely here with current directory being the desktop directory of the user if user really enters just a folder name and not a directory path to create anywhere a directory (tree) which would be possible here, too.
So it is advisable to test on success on creating the folder.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
cd /?
cls /?
del /?
echo /?
goto /?
if /?
md /?
rem /?
set /?
timeout /?
type /?
And read also the Microsoft articles:
Testing for a Specific Error Level in Batch Files
Using command redirection operators

How to use parentheses in .bat files, set command and IF EXIST

Ok, I have batch file, just a simple one that hides and unhides folders.
I don't see why it cannot seem to execute accordingly;
Here is extended sample code:
#echo off
color a
title Folder/Drive hider Service
:jiki
echo Loading...
TIMEOUT /T 2 >nul
goto inputs
:inputs
echo Enabling security...
TIMEOUT /T 2 >nul
cls
goto menu
:menu
if EXIST "%~dp0\Encryption" (set status=Folder is locked.)
if EXIST "%~dp0\Logan_Documents" (set status=Folder is unlocked, to open it, enter open as your `action.)`
cls
echo.
echo STATUS: %status%
echo.
echo ----------------------------------------
echo FOLDER PROTECTOR by Logan
echo ----------------------------------------
echo.
echo Lock = Lock the folder(s)
echo Unlock = Unlock the folder(s)
echo Credits = For more info
echo V = Display your current version
echo Exit = Close the program
echo.
echo ----------------------------------------
echo For more info, just ask Logan!
echo ----------------------------------------
echo.
echo Select your action, %USERNAME%.
echo.
set /p "menu=>"
if /I %menu%== lock goto lock
if /I %menu%== unlock goto unlock
if /I %menu%== credits goto credits
if /I %menu%== v goto version
if /I %menu%== exit goto exit
goto invalid
and also a lot more, and every time I go to execute the script, it just leaves the status variable blank.
Here's what I've tried.
Reconfiguring all variables through a port, which then sorts based on if exist. doesn't work, just leaves status blank.
Using different variables. (Kinda stupid but I didn't want to think that I have all these errors because of a small typo.) Still left error blank.
Appreciate all efforts to resolve my problem and get this program working!
-Logan
if exist should work fine exactly as you use it. You don't strictly need the quotes, since the names don't include spaces. Also you don't need the parentheses since it is a single command.
But then again, it should work with them as well (I actually tested this), so the only thing I can imagine is that the files or folders are not found because the script is running in the wrong directory. After all you use just the names without any path, so the current directory should contain those files.
The 'current directory' isn't necessarily the directory in which the script is saved. If you are in 'C:\Foo' and you call 'C:\Bar\Script.bat', the current directory will still be 'C:\Foo'. The same goes for starting scripts through a shortcut.
To try this, you can use echo %CD% in your script to echo the current directory.
As a possible solution, you can use %~dp0 to use the actual directory in which the batch script is saved, so you always have a starting point to start from:
REM Check if 'Encryption' exists in the same folder as the batch file.
if EXIST "%~dp0\Encryption" (set status=Folder is locked.)
probably neither of the ifs are true, maybe because the active directory is not what you think it is. you can test this easily by inserting a set status=none above the ifs. or insert dir to see what the scrips actually sees at this point.

Resources